C语言程序运行报sysmalloc: Assertion错误是什么原因?如何修复?
报错含义
Hello: malloc.c:2385: sysmalloc: Assertion ... failed
这个错误是glibc的malloc底层校验堆内存元数据失败抛出的致命错误,说明你之前的操作已经破坏了堆区的内存管理结构,第二次调用malloc分配内存时,检测到堆的元数据不符合规范,直接终止程序。
代码存在的问题
- 函数返回值类型不匹配:
makemeunique声明返回char类型,实际返回char*类型的堆地址,类型完全错误。 - 指针类型错配:将
char*类型的xp赋值给int*类型的pp,int类型在绝大多数系统中占4字节,char仅占1字节:- 执行
*pp++=s[i]时,会一次性向地址写入4字节内容,超出你申请的内存边界 pp++每次向后偏移4字节,直接越界访问堆区,覆盖malloc用于管理内存的元数据,这是触发本次崩溃的核心原因
- 执行
- 内存分配未预留结束符位置:你传入的长度
l是strlen(s)的结果,不含字符串结束符\0,申请l字节的内存,后续写入\0时本身就会越界1字节 - 去重逻辑遗漏第一个字符:循环从
i=1开始遍历,完全没有处理s[0],最终结果会丢失原字符串的第一个字符 - 缺少必要头文件:使用了
strlen但没有引入<string.h>,函数未声明的行为是未定义的 - 去重条件可读性差:
if(yes-1)等价于if(yes == 0),写法容易引发逻辑误解 - 堆内存未释放:两个调用返回的
p1、p2没有对应free,存在内存泄漏
修复方案
修改后的完整代码如下:
#include<stdio.h> #include<stdlib.h> #include<string.h> // 修改返回值类型为char* char* makemeunique(char *s, int l) { // 多分配1字节存结束符 char *xp = (char *)malloc((l + 1) * sizeof(char)); // 指针类型改为char*,和xp匹配 char *pp = xp; // 先把第一个字符加进去 if (l > 0) { *pp++ = s[0]; } for(int i = 1; i < l; i++) { int yes = 0; for(int j = i - 1; j >= 0; j--) { if(s[i] == s[j]) { yes = 1; break; // 找到重复就提前退出,优化性能 } } // 改可读性更高的判断条件 if(yes == 0) { *pp++ = s[i]; } } *pp = '\0'; printf("%s\n", xp); return xp; } int main() { char s[9999], x[9999]; // 去掉scanf里的\n,避免多余的空白匹配 scanf("%s%s", s, x); char *p1, *p2; p1 = makemeunique(s, strlen(s)); p2 = makemeunique(x, strlen(x)); // 释放堆内存,避免泄漏 free(p1); free(p2); return 0; }
修改说明:
- 修正函数返回值类型为
char*,匹配返回的堆指针类型 - 将
pp的类型改为char*,避免指针偏移和写入的越界问题 - 内存申请时多分配1字节存储
\0,避免结束符越界 - 补充第一个字符的写入逻辑,避免丢失首字符
- 引入
<string.h>头文件,匹配strlen的声明 - 优化去重判断的可读性,增加重复查找的提前退出逻辑
- 修正
scanf的格式化字符串,避免输入异常 - 补充
free释放申请的堆内存,解决内存泄漏问题
内容的提问来源于stack exchange,提问作者Spark
相关产品推荐
相关产品推荐

