C语言调用realloc报Invalid next size错误,读取文件字符串存入动态数组失败
问题根因
你遇到的Invalid next size错误是典型的堆内存越界破坏导致的,错误出在扩容字符串数组的顺序写反了:
你先执行了dict->size++,紧接着直接给越界的下标dict->words[dict->size]分配内存,此时还没有对dict->words数组做扩容,访问超出了words数组的原有长度,破坏了堆空间的控制元数据,后续调用realloc时检测到堆结构损坏就抛出了错误。
其他待优化问题
- 内存泄漏:函数内
malloc了dictionary结构体,但返回的是结构体值拷贝,原malloc的结构体指针没有释放,造成内存泄漏 - 边界逻辑缺失:如果文件最后一行末尾没有换行符,最后一行内容会被直接丢弃
- 无用分配:初始阶段不需要提前给
words[0]分配内存,可以和扩容逻辑合并
修复后代码
struct Dictionaries { char** words; int size; }; typedef struct Dictionaries dictionary; dictionary get_dict (FILE* fp) { // 直接在栈上创建结构体,避免堆泄漏 dictionary dict; dict.size = 0; int strSize = 0; // 初始分配1个char*空间 dict.words = (char**) malloc(sizeof(char*)); dict.words[dict.size] = malloc(sizeof(char)); while(1) { char c = fgetc(fp); if (c == EOF ){ // 处理最后一行无换行的情况 if (strSize > 0 || dict.size == 0) { dict.words[dict.size][strSize] = '\0'; dict.size++; } break; } if (c == '\n') { dict.words[dict.size][strSize] = '\0'; strSize = 0; dict.size++; // 先扩容words数组,再给新下标分配内存,避免越界 dict.words = (char**) realloc(dict.words, (dict.size + 1) * sizeof(char*)); dict.words[dict.size] = malloc(sizeof(char)); } else { strSize++; dict.words[dict.size] = (char*) realloc(dict.words[dict.size], (strSize + 1) * sizeof(char)); dict.words[dict.size][strSize - 1] = c; } } return dict; }
注意事项
- 使用完返回的
dictionary结构体后,需要先遍历释放所有words数组里的字符串指针,再释放words指针本身,避免内存泄漏 - 实际使用建议加
malloc/realloc的返回值判空逻辑,处理内存分配失败的场景
内容的提问来源于stack exchange,提问作者Joe Nissen
相关产品推荐
相关产品推荐

