0

Segmentation fault (core dumped)

In C, I initialized an array of strings, like this:

char* strings[20];

then tried to fscanf a bunch of stuff.

for(int i = 0; i<20; i++){
  fscanf(file, "%s", strings[i]);
}

although there is more to the program, I am sure that this is the part causing a segmentation fault. A run using gdb stated that the error was in file vfscanf, so I think this is related.

3
  • 1
    you didn't allocate memory for the strings... of course it would crash when you try to write to unknown addresses. Commented Sep 25, 2014 at 0:16
  • how would I go about doing that? I tried also doing malloc(sizeof(char)*20) inside the for loop for each string, but it did not work. I also tried char* strings[20] = {"","","",""...}; to no avail. Commented Sep 25, 2014 at 0:24
  • You tried strings[i]=malloc(sizeof(char)*20) inside the for loop? Are you sure that all 20 strings read are no more than 19 characters (keeping in mind that you need 1 char for the null-terminating character)? Commented Sep 25, 2014 at 0:37

3 Answers 3

5

After your declaration

char* strings[20];  // This is an array of pointer of type char *

You will need to allocate memory for each pointer before you can read into them from the file.

for(int i = 0; i<20; i++){
  strings[i] = malloc(some_size * sizeof(char)); // allocate memory for each pointer first.
  fscanf(file, "%s", strings[i]);
}
Sign up to request clarification or add additional context in comments.

2 Comments

This fscanf has a problem that it does not prevent a buffer overflow if the file contained a long word; and fscanf only allows supplying a compile-time constant as the buffer length. If some_size is not a constant expression, you will need to rewrite this code to use some other input function.
Thanks for pointing it out @MattMcNabb. Just want to illustrate the core issue here. But definitely you're right :)
1

char* strings[20]; does not initialize an "array of string".

Instead strings is an array of 20 char * pointers. A strings in C is array of char up to an including the trailing '\0'. So far, the array Strings[] has indeterminate values and none of the elements certainly point to a string.

By assigning those 20 pointers to various strings, you will have an "array of strings".

// Assign 0 (or NULL) to each pointer.
char* strings[20] = { 0 };

for(int i = 0; i<20; i++){
  char buffer[100];
  if (fscanf(file, "%99s", buffer) != 1) {
    break;
  }
  strings[i] = strdup(buffer);  
  // or
  size_t len = strlen(buffer) + 1;
  strings[i] = memcpy(malloc(len), buffer, len);  // error check omitted
}

Comments

1

Note that if you have a sufficiently modern POSIX-compliant version of scanf() (check your system manual), you can use:

for (int i = 0; i < 20; i++)
{
    if (fscanf(file, "%ms", &strings[i]) != 1)
        …report error and break/return…
}

With the %ms conversion specification, scanf() will use malloc() to allocate the appropriate amount of memory for the string it reads. Don't forget to free() the memory when you're done with it.

Note that Mac OS X (10.9.5 Mavericks) does not have a sufficiently modern version of scanf(). Linux (as found in Ubuntu 14.04, for example), does.

Comments

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.