释放已分配内存时出现堆损坏问题求助
排查堆损坏(Heap-corruption)错误的解决方案
嘿,我来帮你搞定这个堆损坏的问题!先看看你代码里的几个关键问题:
原代码里的核心问题
先把你提供的代码片段贴出来方便分析:
char *temprijec(int rng, RIJEC *B, int *len) { int i; char *temp=(char*)calloc(*len + 1, sizeof(char)); *len = strlen((B + rng)->rijec); for (i = 0; i < *len; i++) { if (i == 0) { temp[i] = (B + rng)->rijec[i]; } else if (i == (*len)) { temp[i] = '\0... } // 这里应该还有其他逻辑? } // 应该要返回temp? }
内存分配时机错误
你先基于传入的*len值分配了temp的内存,但紧接着就把*len覆盖成了目标字符串(B + rng)->rijec的长度。如果新的长度比原来的*len大,temp的空间就会不够,后续写字符时会越界修改堆内存,这就是堆损坏的直接原因。循环边界与终止符错误
- 循环条件是
i < *len,所以i的取值范围是0到*len-1,else if (i == (*len))这个分支永远不会触发。 - 你写的
'\0...是语法错误,字符串终止符应该是'\0',而且不需要在循环里单独处理——calloc已经把内存初始化为0了,或者最后手动加一个即可。
- 循环条件是
冗余的逐个字符复制
其实不需要手动循环复制字符,用标准库的strcpy会更简洁安全,不过先按你的原有逻辑修正。
修正后的代码
char *temprijec(int rng, RIJEC *B, int *len) { int target_len; // 先获取目标字符串的长度 target_len = strlen((B + rng)->rijec); // 用正确的长度分配内存,calloc会自动初始化为0,所以末尾已经有'\0' char *temp = (char*)calloc(target_len + 1, sizeof(char)); if (temp == NULL) { // 别忘了检查内存分配是否成功! *len = 0; return NULL; } // 复制目标字符串的内容 strcpy(temp, (B + rng)->rijec); // 更新len为实际长度 *len = target_len; return temp; }
关键改动说明
- 先获取目标字符串的长度,再用这个长度分配内存,确保空间足够。
- 加入了内存分配失败的检查,避免后续操作空指针。
- 用
strcpy替代手动循环复制,减少出错概率,calloc初始化的内存已经保证末尾有'\0',也可以用strdup一步完成分配和复制(不过strdup是非标准函数,视编译器支持情况而定)。 - 如果你坚持要手动循环复制,那循环条件保持
i < target_len,复制完后手动给temp[target_len] = '\0'(不过calloc已经做了这一步,其实不需要)。
内容的提问来源于stack exchange,提问作者Mx2uler
相关产品推荐
相关产品推荐

