0

ヘッダーをバイナリ データ ファイルの一部として保持するように定義された構造体があります。私はそれを使用して1回読み取りを行い、その情報を使用します。その後、それを使用して別の読み取りを行いたいと思います。再度使用する前に解放する必要がありますか?

いくつかのメモリ エラーが発生しています。これが問題である可能性があります。コードを含めていますが、大まかで、この問題をデバッグしようとした現在の結果です。

void readSlices (struct header fileHead, unsigned long *offsets, FILE *fp, struct car **hashTable, int *tableSize){
    struct TVehicle3D tempVehicle;
    struct BlockHeaderData blockHead;
    struct vertexNode *ptr;
    int sliceNum = 1;
    int i;

    while (sliceNum <= fileHead.slicesStored) {
        fseek (fp, offsets[sliceNum], SEEK_SET);
        fread(&(blockHead),sizeof(blockHead), 1, fp);
        printf ("Type: %d  Size: %d\n", blockHead.objectType,blockHead.size );
        while (blockHead.objectType != 88) {
            if (blockHead.objectType == 86) {
                printf ("Reading slice\n");
                fread(&(tempVehicle),75, 1, fp);

                if (*tableSize < tempVehicle.id) {
                    (*tableSize)++;
                    printf ("increasing tablesize (realloc)\n");
                    *hashTable = realloc(*hashTable, (*tableSize) * sizeof (struct car*));
                };
                if ((*hashTable)[tempVehicle.id].set == 0) {
                    (*hashTable)[tempVehicle.id].set = 1;
                };
                (*hashTable)[tempVehicle.id].sliceOut = sliceNum;
                //printf ("size of table at slice #%d = %d\n",tempVehicle.id, *tableSize);
                tempVehicle.centroid.x = ((tempVehicle.points[0].x)+(tempVehicle.points[1].x)+(tempVehicle.points[2].x)+(tempVehicle.points[3].x))/4;
                tempVehicle.centroid.y = ((tempVehicle.points[0].y)+(tempVehicle.points[1].y)+(tempVehicle.points[2].y)+(tempVehicle.points[3].y))/4;
                tempVehicle.centroid.z = ((tempVehicle.points[0].z)+(tempVehicle.points[1].z)+(tempVehicle.points[2].z)+(tempVehicle.points[3].z))/4;
                ptr = (*hashTable)[tempVehicle.id].node;
                printf ("Set ptr\n");
                for (i = 0; i < sliceNum - (*hashTable)[tempVehicle.id].sliceIn; i++) {
                printf ("Setting loop\n");
                    ptr = (*ptr).node;
                };
                printf ("Setting ptr xyz\n");
                ptr = malloc (sizeof (struct vertexNode));
                ptr->x = tempVehicle.centroid.x;
                (ptr)->y = tempVehicle.centroid.y;
                (ptr)->z = tempVehicle.centroid.z;
                if (tempVehicle.id==1) printf ("centroid x: %d y: %d z: %d\n", tempVehicle.centroid.x, tempVehicle.centroid.y, tempVehicle.centroid.z);
            }
            else fseek (fp, ftell(fp) + blockHead.size, SEEK_SET);
            fread(&(blockHead),sizeof(blockHead), 1, fp);
            //printf ("Type: %d  Size: %d\n", blockHead.objectType,blockHead.size );
        };
        sliceNum++;
    };
}
4

4 に答える 4

2

バッファは何度でも自由に再利用できます。

あなたのコードを見ると、あなたが貼り付けたコードにはptr = malloc(...);決して含まれていないことがわかります。free(ptr);これにより、メモリ リークが発生します。ループmalloc()内にあるため、非常に重大なリークが発生する可能性があります。

編集:一見すると、ここで malloc() を呼び出している理由がまったくわかりません。

于 2012-04-16T18:03:42.047 に答える
2

ここを見て:

  if (*tableSize < tempVehicle.id) {
                (*tableSize)++;
                printf ("increasing tablesize (realloc)\n");
                *hashTable = realloc(*hashTable, (*tableSize) * sizeof (struct car*));
            };
            if ((*hashTable)[tempVehicle.id].set == 0) {
                (*hashTable)[tempVehicle.id].set = 1;
            };

tablesize が 10 で、tempVehicle.id が 11 であるとします。したがって、tablesize を 11 にインクリメントし、hashTable を再割り当てして、11 個の構造体ポインタの配列にします。

hashTable[11]次に、12 番目の要素に繰り返しアクセスして代入しようとします。それはあなたの「無効な読み取り」を説明し、nb。、範囲外の書き込みを行います。

于 2012-04-16T18:39:10.213 に答える
0

「filehead」を再利用しても、それ自体ではエラーは発生しません。プログラムの残りの部分から詳細を確認しなければ、エラーの原因を正確に知ることはできませんが、疑わしい行をいくつか示します。

fread(&(tempVehicle),75, 1, fp);

sizeof(tempVehicle) は 75 バイト以上ですか?

tempVehicleスタックにblockHead割り当てられ、非常に大きい場合、スタック オーバーフローが発生する可能性があります。

どのように*offsets割り当てられますか?少なくともサイズが保証されていfileHead.slicesStoredますか?

于 2012-04-16T18:20:08.323 に答える
0

ざっと見てみると、ここで malloc() を呼び出している理由がまったくわかりません。

RyanS が宣言を節約しようとしているからだと思います。「ptr」は、いくつかの異なる目的のためにループで使用されます (唯一の共通点は、それらすべてが struct vertexNode を含むことです)。

それは良い習慣ではありません。malloc された ptr が割り当てられてから破棄されるため、その目的は明確ではありませんが、ループ内で使用するためのバッファーが必要な場合は、ptr とは別にstruct vertexNodelocal を使用するようにlocal を使用します。struct TVehicle3D

リークについては、マーさんの指摘に注意してください。 これは非常に深刻な問題です。 また、これは型にはまらないステートメントです。

ptr = (*ptr).node; 

を使用するだけptr = ptr->nodeです。

于 2012-04-16T18:33:37.097 に答える