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

释放堆分配内存时触发HEAP CORRUPTION DETECTED错误求助

堆损坏问题的原因及修复方案

1. buffer数组越界写入(直接触发堆损坏)

在readLine函数中,你为*buffer分配了*bufferSize字节内存,但随后执行(*buffer)[(*bufferSize)] = '\0';——该索引超出了内存分配范围(分配的内存索引仅到*bufferSize-1),直接破坏堆结构,导致HEAP CORRUPTION DETECTED错误。

修复方法:分配内存时多留1个字节给字符串终止符:

*buffer = (char*)malloc(sizeof(char) * (*bufferSize + 1));
if (*buffer != NULL)
{
    memcpy(*buffer, tempBuffer, *bufferSize);
    (*buffer)[*bufferSize] = '\0';
}

2. main循环中未释放旧buffer的内存泄漏

每次调用readLine都会重新分配*buffer,但之前分配的buffer内存未被释放,不仅造成内存泄漏,还可能导致后续指针覆盖引发的非法访问。

修复方法:调用readLine前检查并释放旧buffer:

do
{
    if (buffer != NULL)
    {
        free(buffer);
        buffer = NULL;
    }
    lastLine = readLine(&inputStream, &buffer, &bufferSize);
    // 后续逻辑
} while (!lastLine);

3. reverse数组分配空间不足

当lastLine为0时,你会额外写入'\n'和终止符'\0',但原分配的reverse大小仅为bufferSize,会导致越界写入。

修复方法:根据是否需要换行符计算正确的分配大小:

int reverseSize = bufferSize + (lastLine ? 0 : 1) + 1;
reverse = (char*)malloc(sizeof(char) * reverseSize);

4. feof循环导致的空读取问题

while (!feof(intputStream))会在读取到EOF后仍执行一次循环,此时tempBuffer为空,malloc(0)行为未定义,可能引发非法访问。

修复方法:改为通过readLine返回的lastLine标记控制循环,同时在readLine中先判断fgets是否读取成功:

// readLine函数内新增判断
if (fgets(tempBuffer, BUFFER_SIZE, *stream) == NULL)
{
    *bufferSize = 0;
    *buffer = NULL;
    return 1; // 标记为最后一行
}

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 255

int readLine(FILE** stream, char** buffer, int* bufferSize);
void reverseString(char* buffer, char** reverse, int bufferSize, int lastLine);


int main(int argc, char** argv)
{
    char* buffer = NULL;
    char* reverse = NULL;
    int bufferSize = 0;
    int lastLine = 0;

    if (argc < 3)
    {
        printf("Usage: %s <input file> <output file>\n", argv[0]);
        return 1;
    }

    FILE* inputStream = fopen(argv[1], "r");
    FILE* outputStream = fopen(argv[2], "w");

    if (inputStream == NULL || outputStream == NULL)
    {
        printf("Input or output file cannot be opened\n");
        return 1;
    }

    do
    {
        if (buffer != NULL)
        {
            free(buffer);
            buffer = NULL;
        }
        lastLine = readLine(&inputStream, &buffer, &bufferSize);

        if (bufferSize > 0)
        {
            int reverseSize = bufferSize + (lastLine ? 0 : 1) + 1;
            reverse = (char*)malloc(sizeof(char) * reverseSize);
            if (reverse != NULL)
            {
                reverseString(buffer, &reverse, bufferSize, lastLine);
                fputs(reverse, outputStream);
                free(reverse);
                reverse = NULL;
            }
        }

    } while (!lastLine);

    fclose(inputStream);
    fclose(outputStream);

    if (buffer != NULL)
        free(buffer);

    return 0;
}

int readLine(FILE** stream, char** buffer, int* bufferSize)
{
    char tempBuffer[BUFFER_SIZE] = { 0 };
    int lastLine = 0;

    if (*stream == NULL)
        return 1;

    if (fgets(tempBuffer, BUFFER_SIZE, *stream) == NULL)
    {
        *bufferSize = 0;
        *buffer = NULL;
        return 1;
    }

    *bufferSize = strlen(tempBuffer);
    char ignoredChar[100] = { 0 };

    if (tempBuffer[*bufferSize - 1] != '\n')
    {
        while (fgets(ignoredChar, sizeof(ignoredChar), *stream) != NULL)
        {
            size_t len = strlen(ignoredChar);
            if (len > 0 && ignoredChar[len - 1] == '\n')
                break;
        }
        lastLine = feof(*stream) ? 1 : 0;
    }
    else
    {
        lastLine = 0;
    }

    *buffer = (char*)malloc(sizeof(char) * (*bufferSize + 1));
    if (*buffer != NULL)
    {
        memcpy(*buffer, tempBuffer, *bufferSize);
        (*buffer)[*bufferSize] = '\0';
    }

    return lastLine;
}

void reverseString(char* buffer, char** reverse, int bufferSize, int lastLine)
{
    int startingValue = (lastLine ? bufferSize - 1 : bufferSize - 2);
    int wordStart = startingValue, wordEnd = startingValue;
    int index = 0;

    while (wordStart >= 0)
    {
        if (buffer[wordStart] == ' ')
        {
            for (int i = wordStart + 1; i <= wordEnd; i++)
            {
                (*reverse)[index++] = buffer[i];
            }
            if (index < (int)(bufferSize + (lastLine ? 0 : 1)))
            {
                (*reverse)[index++] = ' ';
            }
            wordEnd = wordStart - 1;
        }
        wordStart--;
    }

    for (int i = 0; i <= wordEnd; i++)
    {
        (*reverse)[index++] = buffer[i];
    }

    if (!lastLine)
    {
        (*reverse)[index++] = '\n';
    }
    (*reverse)[index] = '\0';
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 14:15:32