【问题标题】:Cannot free data of a buffer after it was reallocated inside recursive function. What can be the reason?在递归函数内部重新分配缓冲区后,无法释放缓冲区的数据。可能是什么原因?
【发布时间】:2014-10-17 19:56:38
【问题描述】:

所以我遇到了一个问题 - 当我的数据超过缓冲区的初始大小并且我在递归函数中进行重新分配时,我在释放缓冲区时遇到错误。

*malloc: *** 对象 0x100106da0 错误:未分配指针被释放*

代码如下:

void recPrint(FILE *file, char *buffer, int realBufferSize, int bufferSize, char *freeCh, NodePtr* temp){

   //some code here...

    int *intArr = temp -> usedIndices;
    int i = 0;
    for(i = 0; i < 36; i++){
        if(intArr[i] == 1){
            if(i > 9){
                *freeCh = i - 10 + 'a' ;
            }else{
                *freeCh = i + '0';
            }
            realBufferSize++;
            if (realBufferSize >= bufferSize){
                buffer = realloc(buffer, (bufferSize + 100) * sizeof(char)); // <<--- REALLOC here
                bufferSize += 100;
            }
            freeCh++;
            recPrint(file, buffer, realBufferSize, bufferSize, freeCh, &temp -> children[i]);

            //now we need to remove all extra characters till the next turn
            freeCh--;
            *freeCh = '\0';
        }
    }

}

void printTrie(FILE *file, char *initialPath){

    initPath = initialPath;
    if(root.isParent == 0) return;
    char *buffer;
    char *freeCh;
    int *intArr = root.usedIndices;
    int bufferSize = 10;
    int realBufferSize = 1000;

    int i = 0;

    for(i = 0; i < 36; i++){
        buffer = calloc(1001, sizeof(char));
        freeCh = buffer;

        if(intArr[i] == 1){
            if(i > 9){
                *freeCh = i - 10 + 'a' ;
            }else{
                *freeCh = i + '0';
            }

        freeCh++;
        realBufferSize++;
        recPrint(file, buffer, realBufferSize, bufferSize, freeCh, &root.children[i]);
        free(buffer); //<<--- getting error here
        }
    }
}

【问题讨论】:

  • Ла-ла-ла-ла-ла-ла-ла-ла :-)
  • realloc 之后的原始指针值早已不复存在。所述指针的调用者值不会改变,并且在执行realloc 后立即无效(注意它在整个递归调用链中按值传递)。
  • @WhozCraig wow...这里的经典解决方法是什么?
  • @PutinHuylo 在整个调用链(包括发起者)中按地址(指针对指针)传递指针,或者利用rePrint 返回结果始终返回缓冲区指针的当前值当递归展开时,将值推回调用链。要么工作。 R.Sahu 在下面的回答展示了后者,并且绝对是一个工作。
  • @WhozCraig 我都试过了。两者都不适合我......所以当我尝试指向指针的路径时,我正在修补 &buffer 并且我将 char *buffer 作为函数参数。但是后来我对 realloc 有错误!它说它从未分配过。我可以在这里做什么? Return char 也不行,还是一样的错误

标签: c realloc


【解决方案1】:

@WhozCraig 的评论指出了问题所在。这是一个建议的修复方法。

  1. recPrint 返回realloced 缓冲区。

  2. recPrint的返回值上使用free

char* recPrint(FILE *file, char *buffer, int realBufferSize,
               int bufferSize, char *freeCh, NodePtr* temp){

   ....

   // where you recurse...
   buffer = recPrint(file, buffer, realBufferSize, 
                     bufferSize, freeCh, &temp -> children[i]);

   // and always return the *current* buffer pointer back to the caller.
   return buffer;
}

printTrie:

    buffer = recPrint(file, buffer, realBufferSize, bufferSize, freeCh, &root.children[i]);
    free(buffer);

【讨论】:

  • 这两种方法对我都不起作用,当我返回重新分配的缓冲区时,我有同样的错误......可能与递归有关......当我将指针指向指针时,我不能做 realloc在 recPrint 里面,它给了我类似的错误
  • @PutinHuylo 不确定您是否添加了必要的特殊酱汁。递归调用要求您保留 那个 可能调整大小的缓冲区指针返回结果。请参阅上面发布的答案的附录。
  • 好吧,现在我在同一个地方出现以下错误: indexer(6296,0x7fff79c1f310) malloc: *** error for object 0x100200158: 已释放对象的校验和不正确 - 对象可能在被释放后被修改. *** 在 malloc_error_break 中设置断点进行调试
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多