0
   typedef struct {
      void *elems;//address of the memory block
      int elemSize; //
      int logicLen;//number of existing elements in vector
      int allocLen;//allocated space for the vector
  } vector;

  static void InsertNumbers(vector *numbers, long n, long d)
  {
    long k;
    long residue;

    for (k = 0; k < d; k++) {
      residue = (long) (((long long)k * (long long) n) % d);
      VectorAppend(numbers, &residue);
    }
  }



void VectorAppend(vector *v, const void *elemAddr)
{
   void *target=(char*)v->elems + (v->logicLen * v->elemSize);

   if(v->logicLen==v->allocLen){
    v->allocLen*=2;
    v->elems=realloc(v->elems,v->allocLen*v->elemSize);
    assert(v->elems!=NULL);
   }
   memcpy(target,elemAddr,v->elemSize);
   v->logicLen++;
}

次に、次の文を使用して InsertNumbers() を呼び出します

vector aVector;
VectorNew(&aVector, sizeof(long),4);
long first=139269,second=3021377;
InsertNumbers(&aVector,first , second);

3021377 は大きすぎるようです... v->elems=realloc(v->elems,v->allocLen*v->elemSize);v->allocLen=4096 の場合、プログラムがクラッシュし、次のように表示されます:これはヒープの破損が原因である可能性があります。

4

1 に答える 1

7

これはあなたが投稿したコードの問題ではなく、別の場所の問題です。

プログラムがヒープを破損し、ヒープが破損していることをrealloc検出します。

次のように破損を検出する必要があります。

  1. デバッグシンボルを有効にしてください

  2. Valgrind を介してプログラムを実行する

編集:追加したコードに重大なエラーがあります。

void VectorAppend(vector *v, const void *elemAddr)
{
    void *target = (char *) v->elems + v->logicLen * v->elemSize;

    if (v->logicLen == v->allocLen) {
        v->allocLen *= 2;
        // Once you call 'realloc', the value of 'elems' might change
        // This means that 'target' is now INVALID
        // 'target' is based on the old value of 'elems'
        v->elems = realloc(v->elems,v->allocLen*v->elemSize);
        assert(v->elems != NULL);
    }
    memcpy(target, elemAddr, v->elemSize);
    v->logicLen++;
}

これを修正するには、の計算をtarget再割り当ての下に移動します。

void VectorAppend(vector *v, const void *elemAddr)
{
    if (v->logicLen == v->allocLen) {
        v->allocLen *= 2;
        v->elems = realloc(v->elems,v->allocLen*v->elemSize);
        assert(v->elems != NULL);
    }
    void *target = (char *) v->elems + v->logicLen * v->elemSize;
    memcpy(target, elemAddr, v->elemSize);
    v->logicLen++;
}

別のエラー:コードの一部であるコメントにエラーがあり、コメントを真剣に受け止めることをお勧めします。

VectorNew(&aVector, sizeof(long), 4); // allocate 4*4 bytes 

誤解を招くため、コメントに「4*4 バイトを割り当てる」と記載しないでください。いつか、Windows 以外の 64 ビット システムでプログラムをコンパイルすると、8x4 バイトになるでしょう。コメントを削除して、コードを読むだけのほうがよいでしょう。

于 2012-07-28T20:22:28.113 に答える