在RHEL6上,我遇到了realloc()的一个奇怪问题。在程序中的某个时刻,realloc()返回null(旧指针有一个地址,并且有足够的可用内存)。分配的是200个结构元素(下面的结构)。出于某种原因,当我执行realloc()时,它会工作,但是我必须将旧指针分配给新指针。下面是我的代码的简化版本。
这可能不仅仅是一个编程问题,而是一个服务器优化问题。你的意见是什么?
谢谢。

//hearder file
typedef struct  {        /* Variable Node Detail Record */
   long     next;
   long     mask;
   char     *value;
   // more stuff...
} NODETEST;

extern NODETEST *oldNodes;
extern NODETEST *newNodes;

//program
#define MAXSIZE 200

// do some stuff with oldNodes....

int alloc_nodes (void)
{
    // Allocate or grow the table
    oldNodes = (NODETEST *) malloc(MAXSIZE * sizeof(NODETEST));
    if( oldNodes == NULL ) {
            //handle exception...
            exit(1);
      }

    //oldNodes = (NODETEST *) realloc(oldNodes,MAXSIZE * sizeof(NODETEST)); // *** FAILS

    newNodes = (NODETEST *) realloc(oldNodes,MAXSIZE * sizeof(NODETEST));   // *** WORKS

    if( newNodes == NULL ){
        printf("errno=%d\n", errno );
    }else{
        oldNodes = newNodes;            }
}

最佳答案

您的第一次调用大小为s的malloc,然后调用大小为s的realloc。这是错误的:您必须将新的所需大小传递给realloc(与当前大小无关-它不是增量)。在这里,realloc返回它接收到的指针的可能性很大。顺便说一句,现在还不清楚你为什么要用紧跟着amalloc的arealloc。给我们更多的细节。
如果希望动态表的大小自动调整,则需要分配将其大小存储在变量(例如alloc_size)中的初始大小,并将当前占用的元素数保留在另一个变量(例如n_elem)中。当您添加一个元素时,您会增加这个数字。当表满时重新分配它。这是一张素描

NODETEST *newNodes = NULL;
int allocated_elem = 0;
int n_elem = 0;

#define ALLOC_INCR 200

然后每次添加:
if (n_elem >= alloc_size) { // the first time realloc is as malloc since nodes == NULL
    alloc_size += ALLOC_INCR;
    nodes = (NODETEST *) realloc(nodes, alloc_size * sizeof(NODETEST));
    if (nodes == NULL) {
        //handle exception...
        exit(1);
    }
}
// add your element at nodes[n_elem]
n_elem++;

回想一下,当接收到的指针是NULL时,realloc的行为类似于malloc(第一次调用的情况)。因此它分配初始表。随后的调用通过以恒定增量调整大小来重新分配它(这里是200)。其他一些方案也可用于扩大表格,例如,您可以将表格大小乘以从32开始的系数(例如2):
if (n_elem >= alloc_size) { // the first time realloc is as malloc since nodes == NULL
    alloc_size = (alloc_size == 0) ? 32 : alloc_size * 2;

重新获取FAILWORKS注释:很明显,如果您分配oldNodes(在FAIL代码中),那么newNodes将不被分配,并保持其初始值为零(NULL),因为它被声明为全局变量且未初始化(我想,这里是extern)。因此,测试可能会失败。

关于c - 为什么在c中malloc()成功的地方realloc()失败?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26221473/

10-13 04:29