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

C语言堆损坏(Heap Corruption)问题求助:字符串操作异常

解决C字符串操作中的堆损坏与输出异常问题

咱们来梳理下你代码里的几个关键问题,这些正是导致堆损坏(Heap Corruption)和输出异常的根源:

1. 字符串未以'\0'结尾,导致printf输出异常

C语言的字符串必须以'\0'作为结束标记,printf("%s")会一直读取内存直到遇到这个标记。你的str_new函数只分配了等于字符长度的内存,没有给'\0'留位置,这会导致输出乱码或者完全无内容。

修正后的str_new函数:

String str_new(const char * characters) {
    String result;
    result.length = str_getLength(characters);
    // 多分配1字节存储字符串结束符'\0'
    result.data = malloc(result.length + 1);
    memcpy(result.data, characters, result.length);
    // 手动添加结束符
    result.data[result.length] = '\0';
    return result;
}

2. str_append中的内存重分配错误,直接触发堆损坏

你在str_append里调用realloc(str->data, charsLength)是完全错误的——这会把原有字符串的内存缩小到要追加的字符长度,直接覆盖原有数据,后续写入还会导致内存越界,触发堆损坏。

正确的做法是计算**原字符串长度 + 追加字符长度 + 1(给'\0'留位置)**的总内存大小,再进行重分配:

void str_append(String * str, const char * characters) {
    int charsLength = str_getLength(characters);
    int newTotalLength = str->length + charsLength;
    // 分配足够的内存,包含结束符的位置
    str->data = realloc(str->data, newTotalLength + 1);
    // 从原字符串末尾开始复制追加的字符
    memcpy(str->data + str->length, characters, charsLength);
    // 更新长度并添加结束符
    str->length = newTotalLength;
    str->data[str->length] = '\0';
}

这里用memcpy比手动循环更高效,当然循环实现也可以,但要确保索引正确。

3. str_remove中的内存分配与复制逻辑问题

首先,malloc(newSize)同样需要多分配1字节给'\0';其次,你的复制逻辑存在内存越界问题:当i > endIndex时,直接赋值temp[i]会跳过大量位置,导致内存写入越界。

另外,你计算要删除的字符数量时也有误:如果要删除从startIndex到endIndex(包含endIndex)的片段,字符数量应该是endIndex - startIndex + 1,而不是endIndex - startIndex。

修正后的str_remove函数:

void str_remove(String * str, int startIndex, int endIndex) {
    // 修正边界判断:endIndex不能超过str->length-1(因为索引从0开始)
    if (startIndex < 0 || endIndex >= str->length || endIndex < startIndex) {
        return;
    }
    int chunkSize = endIndex - startIndex + 1;
    int newSize = str->length - chunkSize;
    // 多分配1字节存结束符
    char * temp = malloc(newSize + 1);
    // 复制startIndex之前的部分
    memcpy(temp, str->data, startIndex);
    // 复制endIndex之后的部分,目标索引从startIndex开始
    memcpy(temp + startIndex, str->data + endIndex + 1, str->length - endIndex - 1);
    // 添加结束符
    temp[newSize] = '\0';
    // 释放原内存并更新字符串
    free(str->data);
    str->length = newSize;
    str->data = temp;
}

修正后的运行结果

当你替换这些函数后,运行main函数会得到预期的输出:

Hello, 
Hello, this is my first C application.
lo, this is my first C application.

堆损坏(Heap Corruption)大多是因为内存越界写入、内存分配大小不足或者错误释放内存导致的,写C语言字符串的时候一定要记得'\0'的存在,内存大小计算要准确哦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:53:34