C语言堆损坏(Heap Corruption)问题求助:字符串操作异常
咱们来梳理下你代码里的几个关键问题,这些正是导致堆损坏(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

