2012-04-16 12 views
0

私はバイナリデータファイルの一部としてヘッダを保持するように定義された構造体を持っています。私はそれを使って1つの読み取りを行い、その情報を使用します。その後、私はそれを使って別の読みをしたい。もう一度使用するには、それを解放する必要がありますか?メモリエラーなしで複数のファイルの読み込みに構造体を再利用できますか?

私はいくつかのメモリエラーが発生しており、これが問題である可能性があると思います。 Imはコードを含んでいますが、これは大まかで、この問題をデバッグする際の私の試行の結果です。

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++; 
    }; 
} 

答えて

2

あなたは好きなだけ頻繁にバッファを再利用することができます。

コードを見ると、ptr = malloc(...);が表示されますが、貼り付けたコードにはfree(ptr);はありません。これによりメモリリークが発生します。 malloc()がループ内にあり、潜在的に非常に重大なリークが発生する可能性があります。

編集:早見表では、ここでmalloc()をなぜ呼び出すのかは不明です。

+0

ありがとうございます、valgrindとありがとうございます。無効なサイズの読み取り..ループ内で数回.. mallocの有無にかかわらず動作します – RyanS

+0

これらのことを報告する際には具体的にする必要がありますサイズは何ですか?)しかし、私は(ほぼ確実な)原因で別の答えを投稿しました... – delicateLatticeworkFever

0

'filehead'を再使用すると、エラーは発生しません。これは、プログラムの残りの部分からより多くの詳細がなくて、エラーの原因となっている内容を正確に把握することは不可能だが、ここでは疑わしい数行です:

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

は少なくとも75バイトのsizeof(tempVehicle)ですか?

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

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

+0

tempVehicleは少なくとも75ですが、私はsizeofで置き換えたので、そのようにする必要はもうありません。また、それは大きなものであることが保証されています。私のプログラムは、スタックを埋めるのに十分な長さではありません。私はreallocの周りにエラーが発生しています.. – RyanS

0

高速で見ると、malloc()がなぜ呼び出されているのかは分かりません。 ここにあります。

私はRyanSが宣言を保存しようとしているからだと思います。 "ptr"はいくつかの異なる目的のためにループ内で使用されます(唯一の共通点はstruct vertexNodeです)。

これは良い方法ではありません。 malloc'd ptrはそれが投げ捨てられているので明確ではありませんが、ループ内で使用するバッファが必要な場合は、ローカルstruct vertexNodeを使用して、ローカルのstruct TVehicle3Dをptrとは別に使用してください。

リークについてマーズの点に注意してください。 これは非常に深刻な問題です。も:これは、型破りな見通しに関する記述です:

ptr = (*ptr).node; 

ちょうどptr = ptr->nodeを使用しています。ここ

2

ルック:あなたは11の構造体のポインタの配列であることを11とreallocのハッシュテーブルにtablesizeをインクリメントして

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です。

次に、12番目の要素であるhashTable[11]にアクセスして繰り返してみます。それはあなたの "無効な読み込み"を説明し、nbは、を超えての書き込みを行います。

関連する問題