当大小超过8192字节时,为什么realloc()不起作用?

时间:2012-07-28 20:18:40

标签: c memory heap

   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时,程序崩溃并说:这可能是由于堆的损坏 为什么呢?

1 个答案:

答案 0 :(得分:7)

这对您发布的代码不是问题,这是其他地方的问题。

你的程序会破坏堆,然后realloc检测到堆已损坏。

您需要按如下方式检测损坏:

  1. 确保启用调试符号

  2. 通过Valgrind运行程序

  3. 编辑:您添加的代码中存在严重错误。

    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 
    

    评论不应该说,&#34;分配4 * 4&#34;字节,因为这是误导:有一天你将在不是Windows的64位系统上编译程序,它将是8x4字节。您最好删除评论并阅读代码。