3

I have the following code, and I'm a bit confused as to why I'm getting a segmentation fault.

typedef struct {
 int tag;
 int valid;
} Row;
typedef struct {
 int index;
 int num_rows;
 Row **rows;
} Set;
/* STRUCT CONSTRUCTORS */
// Returns a pointer to a new Sow.
// all fields of this row are NULL
Row* new_row() {
 Row* r = malloc(sizeof(Row));
 return r;
}
// Returns a pointer to a new Set.
// the set's index is the given index, and it has an array of
// rows of the given length.
Set* new_set( int index, int num_rows, int block_size ) {
 Set* s = malloc(sizeof(Set));
 s->index = index;
 s->num_rows = num_rows;
 Row* rows[num_rows];
 for (int i = 0; i < num_rows; i++) {
 Row* row_p = new_row();
 rows[i] = row_p;
 }
 s->rows = rows;
 return s;
}
/* PRINTING */
void print_row( Row* row ) {
 printf("<<T: %d, V: %d>>", row->tag, row->valid);
}
void print_set( Set* set ) {
 printf("[ INDEX %d :", set->index);
 for (int i = 0; i < set->num_rows; i++) {
 Row* row_p = set->rows[i];
 print_row(row_p);
 }
 printf(" ]\n");
}
int main(int argc, char const *argv[]) {
 Set* s = new_set(1, 4, 8);
 print_set(s);
 return 0;
}

Basically a Set has a pointer to a array of Rows. I'd think Row* row_p = set->rows[i]; would be the right way to get the row from a set, but I must be missing something.

Kate Gregory
19k8 gold badges59 silver badges87 bronze badges
asked Nov 26, 2012 at 20:31

2 Answers 2

4

You are allocating a local array of Row*s

 Row* rows[num_rows];
 for (int i = 0; i < num_rows; i++) {
 Row* row_p = new_row();
 rows[i] = row_p;
 }
 s->rows = rows;

and let the rows pointer of the Set point to that. The local array doesn't exist anymore after the function returned, so s->rows is then a dangling pointer. Memory that shall still be valid after the function returned must be allocated with malloc (or one of its cousins).

answered Nov 26, 2012 at 20:34
Sign up to request clarification or add additional context in comments.

Comments

1

s->rows is assigned the address of the local variable rows in the function new_set(), which means s->rows is a dangling pointer when new_set() returns. Dynamically allocate an array of Row* to correct:

s->rows = malloc(num_rows * sizeof(Row*));
if (s->rows)
{
 /* for loop as is. */
}

Remember that s->rows, as well as its elements, must be free()d.

answered Nov 26, 2012 at 20:34

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.