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.