1

以下代码引发错误:

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

我不确定发生了什么事。我正在释放我明确 malloc'd 的内存区域,它与传递指向另一个方法的指针有关吗?

#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;
}
4

3 回答 3

8

C 是一种按值传递的语言。buffer您对函数内部所做的修改对inreadstringbuffered()的值没有影响。如果曾经执行过,那么您已经释放了知道的内容,并且当您返回时 - BAM - 双重释放。buffermain()realloc()buffermain

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

void readstringbuffered(char **buffer)

然后*buffer在里面使用。在调用站点,您将使用readstringbuffered(&buffer)传递必要的指针。

于 2013-01-24T19:32:18.320 回答
3

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

于 2013-01-24T19:34:16.017 回答
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;
}
于 2013-01-24T19:36:46.667 回答