如何解决C语言中realloc(): invalid next size错误
解决realloc(): invalid next size错误的方法
核心问题:realloc内存大小计算错误
你的代码里realloc(str_ptr, count + 1)是触发错误的关键——realloc的第二个参数要求是字节数,但你只传入了元素个数。str_ptr是char**类型,每个元素是一个指针(64位系统占8字节,32位占4字节),正确的内存大小应该是(count + 1) * sizeof(char *)。
单词数少的时候,偶然分配的内存刚好能容纳指针,但单词数超过3后,分配的字节数远小于实际需要的指针数组大小,直接破坏堆结构,触发realloc(): invalid next size错误。
其他潜在问题
- word数组溢出风险:定义的
word[20]没有边界检查,若输入单词长度超过19,会越界写入内存,同样可能引发内存破坏。 - 冗余的first变量:单独处理第一个单词的逻辑没必要,统一用realloc逻辑更简洁。
修复后的完整代码
#include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdlib.h> char **process_str(char *str) { char **str_ptr = NULL, **str_ptr2; char *word_ptr; char word[20]; char chr; int i = 0, count = 0, ind = 0, len; if (str == NULL) return NULL; // 初始分配单个指针的空间 str_ptr = malloc(sizeof(char *)); if (str_ptr == NULL) return NULL; len = strlen(str) + 1; while (i < len) { chr = str[i]; if ((chr == ' ' || chr == '\0') && ind > 0) { // 防止word数组越界 if (ind >= sizeof(word)/sizeof(word[0])) { ind = sizeof(word)/sizeof(word[0]) - 1; } word[ind] = '\0'; word_ptr = strdup(word); if (word_ptr == NULL) { // 分配失败时释放已分配资源,避免泄漏 for (int j = 0; j < count; j++) { free(str_ptr[j]); } free(str_ptr); return NULL; } // 统一用realloc处理所有单词的存储 str_ptr2 = realloc(str_ptr, (count + 1) * sizeof(char *)); if (str_ptr2 == NULL) { free(word_ptr); for (int j = 0; j < count; j++) { free(str_ptr[j]); } free(str_ptr); return NULL; } str_ptr = str_ptr2; str_ptr[count] = word_ptr; count++; ind = 0; } else if (chr != ' ') { // 限制word数组写入,防止溢出 if (ind < sizeof(word)/sizeof(word[0]) - 1) { word[ind] = chr; ind++; } } i++; } // 添加NULL终止符,确保指针数组正确结束 str_ptr2 = realloc(str_ptr, (count + 1) * sizeof(char *)); if (str_ptr2 == NULL) { for (int j = 0; j < count; j++) { free(str_ptr[j]); } free(str_ptr); return NULL; } str_ptr = str_ptr2; str_ptr[count] = NULL; return str_ptr; } // 测试代码 int main(void) { int i = 0; char **ptr; char *str = "please please anf dsd it for"; ptr = process_str(str); printf("done step one\n"); if (ptr == NULL) { printf("ptr is NULL"); return 1; } while (ptr[i] != NULL) { printf("String: %s\n", ptr[i]); i++; } // 释放内存,避免泄漏 for (i = 0; ptr[i] != NULL; i++) { free(ptr[i]); } free(ptr); return 0; }
修复要点说明
- 所有
realloc调用都使用(count + 1) * sizeof(char *)计算字节数,确保分配足够的指针存储空间。 - 添加
word数组的边界检查,避免长单词导致的内存越界。 - 简化第一个单词的处理逻辑,统一用realloc管理,代码更简洁易维护。
- 增加内存分配失败时的资源释放逻辑,避免内存泄漏。
- 测试代码中补充内存释放步骤,养成良好的内存管理习惯。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

