1

次のコードはエラーをスローします。

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;
}
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() は、以前に割り当てられたメモリを解放し、別の場所に再度割り当てることができます。これにより、メインのバッファ ポインタが完全に無効になります。参照によってバッファを渡し、それに応じて 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 に答える