c - Trying to copy and allocate this pointer to work with a stack but it gives me a segmentation fault -


so have stack of

struct board_struct {     int rows;      int cols;     char board[max_r][max_c] };  typedef struct stack_s {     board boards[80];     int size; } stack;  typedef struct board_struct board; typedef struct board_struct *boardptr; 

i have

board *boardptr stack stack 

when push want current board put stack , program change , push new board stack

lets pop function

board pop() {      stack->size--;      return stack->boards[stack->size];  } 

here push

void push(boardptr b) {      board n = *b;      stack->boards[stack->size] = n;     stack->size++;  } 

the thing board put stack has separated or copied boardptr , put stack can make changes boardptr later on. when pop set boardptr last board stack.

how can copy board without changing pointer can save stack?

as others have pointed in comments, problem here returning address of local variable. bad, because causes undefined behavior: in effect, you're accessing memory no longer belongs program.

here existing code, annotated highlight problem:

// why passing board pop? it's never used... boardptr pop(board b) {      // result local variable - leave      // pop function, disappears!     // also, assuming indices 0 based,     // returning wrong thing: if stack->size 1,     // want return item @ position 0, not position 1!     board result = stack->boards[stack->size];     stack->size--; //top      // uh-oh! returning pointer result,     // local. value return caller points who-knows     // now!     return &result;  } 

the easiest solution change function not return pointer board, actual board. consider this:

board pop() {     assert (stack->size != 0);      stack->size--;     board result = stack->boards[stack->size];     return result; }  

this works correctly because aren't returning local variable copy of caller. think best , safest option going forward. if want fancy, try version instead, same thing:

board pop() {     assert (stack->size != 0);     return stack->boards[--stack->size]; } 

alternatively, this:

void pop(boardptr b) {     assert (stack->size != 0);     if (b != null)         *b = stack->boards[--stack->size]; } 

caveat emptor: last version, accepts boardptr may not work right if struct contains pointers (see shallow copy , deep copy in c. yours doesn't, fine.