0

文字列のセットを保持するために、概念的にはマトリックスに非常に似た構造を動的に割り当てました。メモリを解放しようとしているときに問題が発生しました。私のコードは次のようになります。

# include <stdio.h> 
# include <string.h>
# include <malloc.h>
# define SIZE 2

typedef struct fork{
char** dataPointersArray;
char*  dataArray;
}fork;

int main(int argc, char* argv[]){

fork forkDS;
int i;
char* dataArrayPtr;
unsigned char data[255] = "some data"; /* this is actually a function's output */
int PtrIndex;

/* allocate memory for the arrays */
    forkDS.dataPointersArray = (char**) calloc(SIZE ,sizeof(char*));

    if(forkDS.dataPointersArray == NULL){
        printf("couldn't allocate memory \n");

    }

    forkDS.dataArray = (char*) calloc(SIZE, 255);

    if( forkDS.dataArray == NULL){
        free(forkDS.dataPointersArray);
        printf("couldn't allocate memory \n");

    }
    dataArrayPtr = forkDS.dataArray;
    for(i = 0; i < SIZE; i++){
    /* update the dataPointers Array */
        forkDS.dataPointersArray[i] = dataArrayPtr;


        /* copy data into data array */
        memcpy(dataArrayPtr,data,20);

        dataArrayPtr[255] = '\0';

        /* update the pointer of the data array */
        dataArrayPtr = dataArrayPtr + 256;
    }


    for (PtrIndex = 0; PtrIndex < 2; PtrIndex++) {
        if (*(forkDS.dataPointersArray + PtrIndex) != NULL) {
            *(forkDS.dataPointersArray + PtrIndex) = NULL;
        }
    }

    /* DEBUG comment -  this 2 lines works */
    free(forkDS.dataArray); 
    forkDS.dataArray = NULL;

    /* DEBUG comment - the next line fails */
    free(forkDS.dataPointersArray);
    forkDS.dataPointersArray = NULL;


return 0;
}

したがって、構造体には実際には 2 つの配列が含まれています。1 つは文字列へのポインターであり、もう 1 つは、終端の \0 で区切られた、1 つずつ整列された文字列を含みます。

コードは正常に機能し、最後の for ループも同様に機能します。free への最初の呼び出しも機能します。問題は、free の最後の呼び出しが失敗することです。この問題に関するすべての可能なデータを検索しようとしましたが、私が見つけたすべての例は、文字列を保持する 2 番目の配列が for ループで段階的に割り当てられ、その後 for ループでも解放される場合を考慮しています。 .

ループ内での動的割り当ての使用を避けたかったため、コードが異なって見えます。

誰が問題が何であるか知っていますか?

================================================== ====================================

私に答えてくれた皆さん、どうもありがとう。最終的に、バグは解決されました。問題は、他のコードで dataPointersArray が SIZE を超える要素で満たされていたことでした。これは最初は無害に見え、実際には free 呼び出しが失敗しました。

コメントありがとうございます!シャチャー

4

2 に答える 2

6

SIZE*255 バイトを割り当てていますが、SIZE * 256 バイトを使用しています。

forkDS.dataArray = (char*) calloc(SIZE, 255); 
dataArrayPtr = forkDS.dataArray;   

//SIZE TIMES loop:
    dataArrayPtr = dataArrayPtr + 256; 

そのため、ポインターを NULL にすると、配列の末尾を越えて配置された制御データが、free が探している malloc によって上書きされる可能性があります。

于 2011-07-19T22:02:26.133 に答える
0

それぞれ 255 文字の SIZE 行で構成される配列にスペースを割り当てました。したがって、各行の最大のインデックスは 254 = 255 - 1 です。\0 文字を書くときは、次の行の先頭に書きます。最後の反復の後、SIZE バイトずれます。

別の詳細: メモリ割り当てのいずれかが失敗した場合、プログラムはエラー メッセージを出力するだけで、後で SEGFAULT を引き起こすことを止めません。

于 2011-07-20T20:35:56.247 に答える