0

My program fails because of a segmentation fault. Using gdb i could see that the trouble was when i was initializing a 2d-array in my function.

My compiler flags were -Wall -Wpedantic -Wextra -Wconversion -std=gnu11

This is the function i'm using. The error raises on line 4. I don't understand why it breaks there, im fairly a beginner to C.

1 char ** get_categories_names(char * file_route, unsigned int maximum_categories) {
2     unsigned int category_counter = 0;
3
4     char ** categories_list = (char **)malloc(maximum_categories * sizeof(char *));
5     char * category = "";
6     FILE * categories_config;
7     categories_config = fopen(file_route, "r");
8
9     if (categories_config == NULL)
10    {
11            perror("Error while opening the file.\n");
12            exit(EXIT_FAILURE);
13    }
14
15    while (fgets(category, 255, categories_config) && category_counter < maximum_categories) {
16            printf("%d", category_counter);
17            categories_list[category_counter] = malloc(100 * sizeof(char));
18            category[strcspn(category, "\n")] = 0;
19            categories_list[category_counter] = category;
20            category_counter++;
21    }
22    fclose(categories_config);
23    return categories_list;

This is the gdb result:

(gdb) step
11              char ** categories_list = (char **)malloc(maximum_categories * sizeof(char *));
(gdb) step
__GI___libc_malloc (bytes=40) at malloc.c:3028
3028    malloc.c: No existe el archivo o el directorio.

And this is the text file i was reading to:

horror
mystery
FPS
memes
comedy
9
  • 1
    Edit the question to provide a minimal reproducible example. Commented Sep 9, 2020 at 16:19
  • 1
    I don't think your seg fault is because of malloc(). It's fgets(category, 255, categories_config). category declared is a pointer to a string literal "". You cant' overwrite that. Declare it as char category[255} instead Commented Sep 9, 2020 at 16:19
  • 1
    .. but other bugs come afterwards, like categories_list[category_counter] = category; You can't copy strings like that. Commented Sep 9, 2020 at 16:20
  • 1
    To expound upon what @IngoLeonhardt posted, where is the memory that the file contents get read into? Commented Sep 9, 2020 at 16:25
  • 2
    Run your code through valgrind. If you're mismanaging memory, it will tell you where. Commented Sep 9, 2020 at 16:30

2 Answers 2

1

There are a number of issues. I'll try to fix then in your code adding comments about the reasons. Please note that I didn't compile so there might be some typos

char ** get_categories_names(char * file_route, unsigned int maximum_categories) {
     unsigned int category_counter = 0;

     // don't cast the result of malloc
     char ** categories_list = malloc(maximum_categories * sizeof(char *));
     // declare category as array to provide memory for fgets()
     char category[255];
     FILE * categories_config;
     categories_config = fopen(file_route, "r");

     if (categories_config == NULL)
     {
           perror("Error while opening the file.\n");
           exit(EXIT_FAILURE);
     }

     // use sizeof array so you don't have to repeat array size
     while (fgets(category, sizeof category, categories_config) && category_counter < maximum_categories) {
              printf("%d", category_counter);
              
              category[strcspn(category, "\n")] = 0;
              // alloc the right size -- sizeof( char ) is always 1 and can be omitted
              categories_list[category_counter] = malloc(strlen(category)+1);
              // copy strings w/ strcpy()
              strcpy(categories_list[category_counter], category);
              // the two commands above could be replaced by
              //categories_list[category_counter] = strdup(category);
              category_counter++;
      }
      fclose(categories_config);
      return categories_list; 

Besides, malloc() could return NULL. That should be checked too

Sign up to request clarification or add additional context in comments.

2 Comments

this really helped, thanks! btw, any reason why gdb would stop on the array allocation? instead inside the while when i was debugging, that really confused me
glad i could help. I'm sorry but with this information I can't say anything about what you've experienced with gdb. Is still recommed tou run your program with valgrind too. That might show some errors that don't lead to an observable problem. Due to the nature of Undefined Behaviour everything seems to work although your code is broken
1

regarding;

(gdb) step
11              char ** categories_list = (char **)malloc(maximum_categories * sizeof(char *));
(gdb) step
__GI___libc_malloc (bytes=40) at malloc.c:3028
3028    malloc.c: No existe el archivo o el directorio.

This is NOT saying that a seg fault event occurred.

Rather, it is saying that you do not have the source code for 'malloc.c' visible to gdb

To avoid this kind of problem, suggest:

(gdb) step
11              char ** categories_list = (char **)malloc(maximum_categories * sizeof(char *));
(gdb) next

which will exec the call to malloc(), but not stop until the next statement in your code

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.