malloc 初始化二维数组时出现分段错误

segmentation fault on malloc initializating 2d-array

我的程序由于分段错误而失败。使用 gdb 我可以看到问题出在我在函数中初始化二维数组时。

我的编译器标志是 -Wall -Wpedantic -Wextra -Wconversion -std=gnu11

这是我正在使用的功能。错误在第 4 行出现。我不明白为什么它在那里中断,我是 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;

这是 gdb 结果:

(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.

这是我正在阅读的文本文件:

horror
mystery
FPS
memes
comedy

有很多问题。然后我会尝试在您的代码中添加有关原因的注释来修复。请注意,我没有编译所以可能会有一些拼写错误

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; 

此外,malloc()可以returnNULL。那也应该检查一下

关于;

(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.

这并不是说发生了段错误事件。

而是说您没有 gdb

可见的 'malloc.c' 的源代码

为避免此类问题,建议:

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

这将执行对 malloc() 的调用,但不会停止,直到您的代码中的下一个语句