使用realloc为char指针数组扩容时触发段错误的问题排查
realloc为char指针数组扩容时触发段错误的问题排查
嘿,我来帮你捋捋这段代码里的问题,你遇到的段错误其实是数组越界访问加上错误的realloc逻辑导致的,咱们一步步拆解:
首先看你初始化word_list的部分:
word_list = (char **)malloc(sizeof(char*));
这里你只给word_list分配了能存1个char指针的空间,但你的word_nb是3,意味着你需要一个能装3个char*的数组。后面你直接访问*(word_list + (word_nb-1))(也就是word_list[2]),这已经超出了初始分配的内存范围,属于非法内存访问,直接触发段错误是必然的。
然后再看你的realloc循环:
for(int a = 0; a < word_nb; a++) { *(word_list + (word_nb-1)) = (char *)realloc(*(word_list + (word_nb-1)), sizeof(word)); }
这里有两个明显的问题:
- 循环里每次都操作同一个元素
word_list[word_nb-1],完全没处理其他的word_list[0]、word_list[1],逻辑完全跑偏了 sizeof(word)得到的是char*的大小(比如64位系统是8字节),而不是你要存的字符串的字节数,这根本达不到扩容单个字符串的目的
另外还有一个潜在问题:你初始给*word_list和word分配的是sizeof(char),也就是1字节,连字符串的终止符\0都放不下,这样后续存字符串肯定会出问题。
正确的修正思路
- 首先要给
word_list分配足够容纳word_nb个char指针的空间,而不是1个:
word_list = malloc(sizeof(char*) * word_nb); // 注意:C里malloc不需要强制类型转换,强制转换反而可能隐藏一些类型问题
如果之后还要扩容word_list本身(比如增加单词数量),应该用realloc来调整这个指针数组的大小,比如:
char **temp = realloc(word_list, sizeof(char*) * new_word_nb); if (temp == NULL) { // 内存分配失败,要处理错误,避免丢失原指针 printf("error reallocating word list\\n"); // 可以选择释放原内存或者做其他处理 free(word_list); exit(EXIT_FAILURE); } word_list = temp;
- 对于每个单词的内存分配,应该根据实际字符串的长度来分配(记得多留1字节存
\0),比如如果你的单词存在word里,应该这样:
// 假设word已经存了有效的字符串 word_list[a] = malloc(strlen(word) + 1); if (word_list[a] == NULL) { // 错误处理 } strcpy(word_list[a], word);
如果之后要扩容某个单词的内存,才需要对word_list[a]用realloc,并且要根据新的长度来计算大小。
修正后的简化示例代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int word_nb = 3; char **word_list; // 先给指针数组分配足够容纳word_nb个指针的空间 word_list = malloc(sizeof(char*) * word_nb); if (word_list == NULL) { printf("error word list allocation\\n"); return EXIT_FAILURE; } // 为每个单词分配内存(这里用示例字符串) const char *sample_words[] = {"hello", "world", "test"}; for (int a = 0; a < word_nb; a++) { word_list[a] = malloc(strlen(sample_words[a]) + 1); if (word_list[a] == NULL) { printf("error allocating word %d\\n", a); // 分配失败要释放已分配的内存,避免内存泄漏 for (int i = 0; i < a; i++) { free(word_list[i]); } free(word_list); return EXIT_FAILURE; } strcpy(word_list[a], sample_words[a]); } // 如果之后需要扩容指针数组(比如增加到5个单词) int new_word_nb = 5; char **temp = realloc(word_list, sizeof(char*) * new_word_nb); if (temp == NULL) { printf("error reallocating word list\\n"); // 清理已有内存 for (int i = 0; i < word_nb; i++) { free(word_list[i]); } free(word_list); return EXIT_FAILURE; } word_list = temp; word_nb = new_word_nb; // 可以继续给新的位置分配单词内存... // 最后记得释放所有内存 for (int i = 0; i < word_nb; i++) { free(word_list[i]); } free(word_list); return EXIT_SUCCESS; }
总结一下,你原来的段错误核心原因是初始指针数组分配空间不足,导致越界访问非法内存,再加上realloc的逻辑完全错误。先把指针数组的大小分配对,再逐个处理每个单词的内存,就能解决问题啦。
备注:内容来源于stack exchange,提问作者XonoGalaxy
相关产品推荐
相关产品推荐

