释放未分配的指针

时间:2013-01-24 19:30:46

标签: c memory memory-leaks

以下代码抛出错误:

mem(44582)malloc: *对象0x7f9f8a4000e0的错误:未释放指针被释放 * 在malloc_error_break中设置断点以进行调试 中止陷阱:6

我不确定发生了什么。我释放了一个显式malloc的内存区域,它是否与传入指向另一个方法的指针有关?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFERSIZE 10

void readstringbuffered(char *buffer);

int main(int argc, char const *argv[])
{
    char *buffer = (char *)malloc(BUFFERSIZE);
    readstringbuffered(buffer);                                               
    printf("%s",buffer);
    free(buffer);

    return EXIT_SUCCESS;
}

void readstringbuffered(char *buffer) 
{
    FILE *source;
    source = fopen("hello.txt","r");
    int current_size = BUFFERSIZE;
    int len = 0;
    int c;
    while((c = fgetc(source)) != EOF)
    {
        if(len == current_size-1)
        {
            current_size *= 2;
            char *temp = (char *)realloc(buffer,current_size);
            if(!temp)
            {
                fprintf(stderr,"out of memory");
                exit(1);
            }
            buffer = temp;
        }
        buffer[len] = c;
        len++;
    }
    buffer[len] = 0;
}

3 个答案:

答案 0 :(得分:8)

C是一种按值传递的语言。您在buffer函数中对readstringbuffered()所做的修改不会影响buffermain()的值。如果realloc()已执行,您已经释放buffer知道的main,当您返回时 - BAM - 双倍免费。

一种可能的解决方案是将指针传递给buffer,而不是buffer本身。将readstringbuffered()的签名更改为:

void readstringbuffered(char **buffer)

然后在其中使用*buffer。在呼叫站点,您可以使用readstringbuffered(&buffer)传递必要的指针。

答案 1 :(得分:3)

realloc()可以释放先前分配的内存并在其他地方再次分配,这使得主缓冲区指针完全无效。您可以通过引用传递缓冲区并使readtringbuffered()相应地修改它,或者返回指向缓冲区而不是void的指针。

答案 2 :(得分:2)

main()中的缓冲区指针不会根据readstringbuffered()中的重新分配进行修改,您可以使用指向缓冲区指针的指针(pBuffer)来回写缓冲区指针,像这样:

void readstringbuffered(char** pBuffer,size_t* pSize) 
{
    char* buffer = *pBuffer;
    size_t size = MIN_SIZE;
    char* newBufferPtr = (char*) realloc(buffer,size);
    if(newBufferPtr)
    {
        buffer = newBufferPtr;            
    }
    else
    {
        //out of memory
        free(buffer);
        buffer = NULL;
        size = 0;
    }

    if(buffer)
    {
        //fill the buffer
    }

    //must always execute
    *pBuffer = buffer;
    *pSize = size;
}

int main(int argc, char const *argv[])
{
    char* buffer = NULL;
    size_t size = 0;
    readstringbuffered(&buffer,&size);
    if(buffer)
    {
        printf("%s",buffer);
        free(buffer);
    }
    else
    {
        //error
    }

    return EXIT_SUCCESS;
}