如果新块大小小于初始值,我应该强制执行realloc检查吗?

And*_*anu 7 c realloc

在这种情况下realloc会失败吗?

int *a = NULL;

a = calloc(100, sizeof(*a));
printf("1.ptr: %d\n", a);

a = realloc(a, 50 * sizeof(*a));
printf("2.ptr: %d\n", a);

if(a == NULL){
    printf("Is it possible?\n");
}

return (0);
Run Code Online (Sandbox Code Playgroud)

}

我的输出是:

1.ptr: 4072560
2.ptr: 4072560
Run Code Online (Sandbox Code Playgroud)

所以'a'指向相同的地址.那么我应该强制执行realloc检查吗?

稍后编辑:

  • 在Windows XP下使用MinGW编译器.
  • 这个行为与Linux上的gcc类似吗?

稍后编辑 2:检查这种方式可以吗?

int *a = NULL, *b = NULL;

a = calloc(100, sizeof(*a));
b = realloc(a, 50 * sizeof(*a));

if(b == NULL){
    return a;
}
a = b;
return a;
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 7

是的,您应该始终对realloc或任何其他内存分配强制执行检查.

重用相同地址的当前行为是不应依赖的实现细节.这样做只是在库切换它的实现或移动到新平台时打开自己的bug.

这可能会失败吗?可能不是,如果你能找到一个案例,我会感到震惊.然而,这并不意味着它不会.在一个自动检查每个操作的函数中包装realloc很简单,没有理由不这样做.

void* xrealloc(void* ptr, size_t size) {
  ptr = realloc(ptr, size);
  if ( !ptr ) {
    exit(EXIT_FAILURE);
  }
  return ptr;
}
Run Code Online (Sandbox Code Playgroud)

  • @hanno,我不能,坦率地说,如果可能的话,我会感到惊讶.但是使用它作为证明它不会失败的证据就是从igonorance做出论证.我更喜欢使用包装函数来检查所有情况下的返回值.这样做更安全. (3认同)
  • @hanno:如果您的malloc实现使用bibop分配器,并且较小的大小需要在新页面上进行,但页面分配器无法分配页面,则realloc可能会失败.当然,智能分配器可能会选择不释放旧块并返回它,但可以想象它可以返回NULL (2认同)

MSN*_*MSN 5

如果realloc在传递小于原始分配的大小时失败将会令人惊讶,但C标准(7.20.3.4)中没有任何内容保证它将始终成功:

realloc函数释放指向的旧对象,ptr并返回指向具有指定大小的新对象的指针size.新对象的内容应与解除分配之前的旧对象的内容相同,直到新旧大小中的较小者为止.新对象中超出旧对象大小的任何字节都具有不确定的值.

如果ptr是空指针,则该realloc 函数的行为类似于malloc 指定大小的函数.否则,如果ptr不匹配的指针早些时候返回 calloc,mallocrealloc功能,或如果空间已经到呼叫释放freerealloc 功能,该行为是不确定的.如果无法分配新对象的内存,则不会释放旧对象,并且其值不会更改.

返回

realloc函数返回指向新对象的指针(可能与指向旧对象的指针具有相同的值),如果无法分配新对象,则返回空指针.

一个非常简单的符合实现realloc将是这样的:

void *realloc(void *ptr, size_t size)
{
    void *new_ptr= malloc(size);
    if (new_ptr && ptr)
    {
        size_t original_size= _get_malloc_original_size(ptr);
        memcpy(new_ptr, ptr, min(original_size, size));
        free(ptr);
    }

    return new_ptr;
}
Run Code Online (Sandbox Code Playgroud)

在低内存条件下(或malloc将返回的任何条件NULL),这将返回NULL.

如果原始分配的大小大于或等于请求的大小,则返回相同的指针也是一种非常简单的优化.但是C标准中的任何内容都没有规定.