malloc/free出现double free or corruption错误排查求助
看起来你遇到的堆内存错误,根源是几个明显的内存操作不当,我来帮你拆解分析:
核心问题1:malloc分配的内存不足,导致堆溢出
你这里的malloc只分配了strlen(a)+strlen(b)字节:
MessageOut = (char*)malloc(strlen(a)+strlen(b));
但当你用sprintf(MessageOut, "%s%s", a, b)拼接字符串时,会写入strlen(a)+strlen(b)个字符,再加上字符串末尾必须的'\0'终止符,总共需要**strlen(a)+strlen(b)+1字节**。内存不足会直接溢出,破坏malloc内部的堆管理结构——第一次循环可能只是轻微破坏,还没触发错误,但几次循环后堆结构彻底混乱,就会触发double free or corruption的报错。
核心问题2:无效的sprintf调用,触发未定义行为
看你初始化a和b的代码:
sprintf(a,"blablabla",strlen(a)); sprintf(b,"blablabla",strlen(b));
格式字符串"blablabla"里没有任何占位符(比如%d),但你却传递了额外的参数strlen(a)/strlen(b)。这种用法属于未定义行为,可能会随机篡改内存数据,进一步加剧堆结构的损坏。而且strlen(a)在a未初始化的情况下调用,会读取栈上的随机数据直到遇到'\0',这也是未定义行为。
核心问题3:指针打印的错误用法
你用printf("%x\n",(uint)MessageOut);打印指针地址,在64位系统上uint是32位类型,会截断64位指针的高位,导致显示的地址不完整。正确的做法是用%p格式符:
printf("%p\n", MessageOut);
修复方案
我把修复后的关键代码片段列出来,你可以参考:
void programm(){ ... 创建变量并从socket获取信息 ... char a[512] = {0}; // 初始化栈数组,避免未定义行为 char b[512] = {0}; // 修复sprintf调用:如果是赋值固定字符串,用strcpy更安全 strcpy(a, "blablabla"); strcpy(b, "blablabla"); // 或者如果需要格式化包含长度的字符串,要对应占位符(示例) // sprintf(a, "blablabla length: %zu", strlen(a)); char* MessageOut = NULL; size_t total_len = strlen(a) + strlen(b); // 分配足够的内存,包括'\0'的空间 MessageOut = malloc(total_len + 1); if(MessageOut == NULL) { printf("MessageOut Is Null\n"); return; // 内存分配失败,直接返回避免后续错误 } printf("%p\n", MessageOut); printf("Size of Malloc: %zu\n", total_len + 1); // 拼接字符串 sprintf(MessageOut, "%s%s", a, b); // 修改前4个字节 MessageOut[0] = 0x02; MessageOut[1] = Data[1]; MessageOut[2] = Data[2]; MessageOut[3] = 0x03; // sendto的长度是实际要发送的字节数,这里是total_len(因为修改的是内容,长度不变) ssize_t byte_nb = sendto(client_socket, MessageOut, total_len, 0, (struct sockaddr *)&dist_addr, addr_len); if (byte_nb == -1) { printf("send error: %s\n", strerror(errno)); } else { printf("%zd bytes sent\n", byte_nb); } printf("%s\n", MessageOut); printf("%p\n", MessageOut); free(MessageOut); MessageOut = NULL; // 置空防止野指针 printf("Test\n"); }
额外说明
为什么第一次循环正常,几次后才报错?因为堆内存的损坏是渐进式的:第一次溢出可能只是破坏了堆的管理元数据,但glibc的内存检查机制还没检测到;后续几次malloc/free操作不断读写损坏的堆结构,最终触发了内存错误提示。
内容的提问来源于stack exchange,提问作者Thierry

