You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在HTTP服务器的handleConnection函数中两次调用malloc触发malloc(): corrupted top size终止错误的求助

解决你的malloc崩溃问题

嘿,我帮你捋捋这个malloc(): corrupted top size错误的根源——你的代码里有好几处内存操作的硬伤,先从最致命的地方说起:

1. 0字节malloc的致命问题

你第一次调用malloc(getHeaderSize)的时候,getHeaderSize初始是0。虽然C标准允许malloc(0)返回一个指针,但这块内存完全没有可用空间,后续的strcat(getHeader, &tempBuffer)直接往超出分配的内存里写,直接把堆结构搞坏了——这就是后续malloc崩溃的根源。

而且strcat要求目标字符串必须以'\0'结尾,你分配的0字节内存连放结束符的空间都没有,这直接导致strcat的行为完全不可控,进一步乱改内存。

2. 错误的字符拼接方式

你用strcat拼接单个字符的操作本身就错了:strcat的第二个参数得是一个以'\0'结尾的字符串,但你传的是&tempBuffer,这只是个指向单个字符的指针,strcat会一直往后读直到找到'\0',这会把未知内存里的内容也拼进去,彻底搞乱堆。

3. 第二次malloc的崩溃只是表象

当你执行char* path = malloc(pathSize)时,pathSize也是0,这时候堆已经被前面的操作搞烂了,malloc的堆检测机制直接触发了崩溃提示——其实真正的问题早就发生了。

给你改好的代码方案

我把这些问题都修复了,还加了必要的错误处理:

int handleConnection(int sockfd) {
    struct sockaddr_in client;
    socklen_t clientLength = sizeof(struct sockaddr_in);
    int new_sockfd = accept(sockfd, (struct sockaddr*)&client, &clientLength);
    if (new_sockfd == -1) {
        perror("accept failed");
        return -1;
    }

    // 初始分配一个合理的缓冲区,别搞0字节了
    size_t getHeaderSize = 1024;
    char *getHeader = malloc(getHeaderSize);
    if (!getHeader) {
        perror("malloc failed for getHeader");
        close(new_sockfd);
        return -1;
    }
    // 先把字符串初始化为空
    getHeader[0] = '\0';
    size_t currentLength = 0;

    char tempBuffer;
    int matchedTerminators = 0;
    char terminators[2] = {'\r', '\n'};

    while(matchedTerminators != 2) {
        ssize_t recvResult = recv(new_sockfd, &tempBuffer, 1, 0);
        // 处理recv出错或者连接断开的情况
        if (recvResult <= 0) {
            break;
        }

        if(tempBuffer == terminators[0] || tempBuffer == terminators[1]) {
            matchedTerminators++;
        } else {
            matchedTerminators = 0;
            // 检查缓冲区是否够,不够就扩容
            if (currentLength + 2 > getHeaderSize) {
                getHeaderSize *= 2; // 每次扩容一倍
                char *temp = realloc(getHeader, getHeaderSize);
                if (!temp) {
                    perror("realloc failed");
                    free(getHeader);
                    close(new_sockfd);
                    return -1;
                }
                getHeader = temp;
            }
            // 手动添加字符,自己管理结束符,别用strcat了
            getHeader[currentLength++] = tempBuffer;
            getHeader[currentLength] = '\0';
        }
    }

    printf("%s\n", getHeader);

    // 提取路径的时候也先分配初始空间
    size_t pathSize = 256;
    char* path = malloc(pathSize);
    if (!path) {
        perror("malloc failed for path");
        free(getHeader);
        close(new_sockfd);
        return -1;
    }
    path[0] = '\0';

    /* 这里写你的路径提取逻辑,记得也要处理内存扩容和字符串结束符 */

    free(path);
    free(getHeader);
    close(new_sockfd); // 别忘了关socket,不然会漏资源!
    return 0;
}

关键修复点说明

  • 告别0字节malloc:初始分配一个合理的缓冲区大小(比如1024字节),不够用就用realloc动态扩容。
  • 正确管理字符串:自己跟踪字符串长度,每次加完字符都手动加'\0',别用strcat处理单个字符——既低效又容易出错。
  • 加错误检查:对malloc、realloc、accept、recv的返回值都做检查,出错就及时释放资源退出,别硬撑。
  • 关闭socket:处理完连接一定要关new_sockfd,不然系统资源会被慢慢耗光。

额外小建议

  • 接收HTTP请求头的时候,可以一次性读更大的缓冲区(比如4096字节),不用逐个字符读,效率会高很多。
  • 提取路径的时候,可以手动遍历getHeader,找到GET 之后到第一个空格的内容,记得处理请求格式不对的情况哦。

内容的提问来源于stack exchange,提问作者c00l

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 12:02:38