【问题标题】:why realloc() doesn't work when size larger than 8192 bytes?为什么当大小大于 8192 字节时 realloc() 不起作用?
【发布时间】:2012-07-28 20:18:40
【问题描述】:
   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-&gt;elems=realloc(v-&gt;elems,v-&gt;allocLen*v-&gt;elemSize);我发现当v->allocLen=4096时,程序崩溃并说:这可能是由于堆的损坏 为什么?

【问题讨论】:

  • 你能告诉我们更多的周边代码吗?这条线没有错。
  • @Mysticial ptr=realloc(ptr, N); 总是错误的,尽管这不太可能是问题所在。一个显示问题的最小但完整的示例将非常有用。
  • @Flexo:如果后面跟着if (!ptr) abort(); 或类似的东西,这并没有错,但是是的,它经常是错误的。
  • @DietrichEpp 它总是错误的,因为当realloc retval 为NULL 时,如果没有其他指针指向ptr 指向的内容,它可能会导致内存泄漏
  • @pb2q:在退出的程序中不可能导致内存泄漏,因为退出程序会释放所有内存。不是每个人都想为每个分配编写错误处理代码,当他们打算用abort()处理它们时。

标签: c memory heap-memory


【解决方案1】:

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

发生的情况是您的程序损坏了堆,然后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++;
}

另一个错误:你的 cmets 有一个错误,这是代码的一部分,我建议认真对待 cmets。

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

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

【讨论】:

    猜你喜欢
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2019-08-15
    • 2021-06-10
    • 2019-06-29
    • 1970-01-01
    相关资源
    最近更新 更多