1

在 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;            }
}
4

1 回答 1

1

您第一次调用malloc大小 S,然后realloc使用相同大小 S。这是错误的:您必须传递给 realloc新的所需大小(独立于当前大小 - 它不是增量)。在这里,很有可能realloc返回它收到的完全相同的指针。顺便说一句,不清楚为什么要使用 amalloc紧随其后的 a realloc。给我们更多的细节。

如果您想要一个大小自动调整的动态表,您需要分配一个初始大小,将其大小存储在一个变量(例如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代码中) thennewNodes没有分配并保持其初始值为零(NULL),因为它被声明为全局变量并且没有初始化(我想,它在extern这里)。因此,测试if (newNodes == NULL)可能会失败。

于 2014-10-07T08:03:18.237 回答