繁体   English   中英

尝试释放堆分配时出错 memory

[英]Getting error when trying release heap-allocated memory

我正在开发一个从输入文件中逐行读取文本的程序。 读取该行后,程序会反转该字符串中单词的顺序,将其打印到 output 文件并开始读取下一行。 我的程序只从一行中读取特定数量的字符,这意味着如果该行包含的字符多于该特定数量,则必须跳过所有字符,直到到达下一行。 我的程序似乎运行良好。

任务要求之一是使用动态分配的 arrays。这是我的主要问题所在的部分。 一旦我尝试释放堆分配的 memory,程序就会失败并显示错误消息: HEAP CORRUPTION DETECTED 一定是我在与他们合作时搞砸了一些事情。 但是,我找不到真正的原因。

#include <stdio.h>
#include <stdlib.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;

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

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

    while (!feof(intputStream))
    {
        lastLine = readLine(&intputStream, &buffer, &bufferSize);

        reverse = (char*)malloc(sizeof(char) * bufferSize);
        if (reverse != NULL)
        {
            reverseString(buffer, &reverse, bufferSize, lastLine);
            fputs(reverse, outputStream);
        }

    }

    fclose(intputStream);
    fclose(outputStream);

    free(buffer);
    free(reverse);

    return 0;
}

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

    if (*stream != NULL)
    {
        fgets(tempBuffer, BUFFER_SIZE, *stream);
        char ignoredChar[100] = { 0 };

        *bufferSize = strlen(tempBuffer);
        // Ignoring in the same line left characters and checking if this is the last line
        if (tempBuffer[(*bufferSize) - 1] != '\n')
        {
            fgets(ignoredChar, 100, *stream);
            if (!feof(*stream))
                lastLine = 1;
        }
        // Allocating memory and copying line to dynamically-allocated array
        *buffer = (char*)malloc(sizeof(char) * (*bufferSize));
        if (*buffer != NULL)
        {
            memcpy(*buffer, tempBuffer, (*bufferSize));
            (*buffer)[(*bufferSize)] = '\0';
        }
    }
    // Return whether or not the last line is read
    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] == ' ')
        {
            int i = wordStart + 1;
            while (i <= wordEnd)
                (*reverse)[index++] = buffer[i++];
            (*reverse)[index++] = ' ';
            wordEnd = wordStart - 1;
        }
        wordStart--;
    }

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

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

问题之一是在readLine中,您可以像这样分配和复制字符串(代码缩短为相关部分):

*bufferSize = strlen(tempBuffer);
*buffer = (char*)malloc(sizeof(char) * (*bufferSize));
(*buffer)[(*bufferSize)] = '\0';

不会为空终止符分配空间。 并且您将在分配的 memory的范围之外写入空终止符。这会导致未定义的行为

您需要为空终止符分配一个额外的字节:

*buffer = malloc(*bufferSize + 1);  // +1 for null-terminator

[请注意,我不转换 result ,也不使用sizeof(char)因为它被指定为始终等于1 。]

另一个问题是因为您没有在bufferSize中包含空终止符,因此main中的reverse分配也将是错误的:

reverse = (char*)malloc(sizeof(char) * bufferSize);

当然应该改为:

reverse = malloc(bufferSize + 1);  // +1 for null-terminator

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM