0

I have a following struct:

strcut records
{
    char **lines;
    int count;
}

There is a function get_pwent() which the concerning code is like this:

struct records *passwd = malloc(sizeof(strcut records));
passwd->lines = malloc(sizeof(char *) * MAX_STR_SIZE);

With a few malloc error checking (passwd is not null, passwd->lines is not null) it's passed down to my parse_file():

parse_file(struct records *record, FILE * in)
{
    int i = 0;

    ... // a while loop
    fgets((*record).lines[i], MAX_STR_SIZE, in); // <-- Segment fault here
    i++;
    ... // end while
}

The file is /etc/passwd and I want to read in the first line of this file and store that into the struct records lines[i] position.

I also tried this:

fgets(record->lines[i], ...) //which also gets a seg fault.

in GDB, under parse_file() scope:

(gdb) p record
$1 = {struct records *} 0x602250

How can I fix this error?

3
  • Did you make sure record is not NULL, record->lines is not NULL, and record->lines[i] is a string allocated with MAX_STR_SIZE? Commented Oct 15, 2014 at 18:33
  • @crashmstr I made sure that passwd (record in parse_file scope) is not NULL, and so does its lines. Commented Oct 15, 2014 at 18:36
  • 1
    I suspect allocating actual memory for the target of that fgets will considerably increase chances for success. Right now you allocate the array of pointers, but the value of each pointer is indeterminate. You allocate no space for the actual string read. With that, you invoke undefined behavior, and (fortunately) crash in the process. Commented Oct 15, 2014 at 18:39

2 Answers 2

2

You need to allocate memory for each line before you can copy data to it:

  record->line[i] = malloc(MAX_STR_SIZE+1);    // allocate memory first.
  fgets((*record).lines[i], MAX_STR_SIZE, in); // <-- Segment fault here
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the quick answer. Initially I thought there was no need to allocate record->line[i] because it was an array of pointers to char * but I was wrong.
2

You're missing an allocation step; for each passwd->lines[i], you need to do another allocation:

// Allocate space for array of pointers
passwd->lines = malloc( sizeof *passwd->lines * max_number_of_strings );
for ( size_t i = 0; i < max_number_of_strings; i++ )
{
  // Allocate space for each string
  passwd->lines[i] = malloc( sizeof *passwd->lines[i] * max_string_length );
}

1 Comment

Thank you very much, I will make a note for myself of that.

Your Answer

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.