如果失败,realloc 会释放前一个缓冲区吗?
Posted
技术标签:
【中文标题】如果失败,realloc 会释放前一个缓冲区吗?【英文标题】:Does realloc free the former buffer if it fails? 【发布时间】:2010-12-09 02:02:08 【问题描述】:如果 realloc 失败并返回 NULL 是前一个缓冲区被释放还是保持原样?我没有在手册页中找到那条特定的信息,我很不确定该怎么做。如果内存被释放,那么双重释放可能会有风险。如果没有,就会发生泄漏。
【问题讨论】:
【参考方案1】:不,它没有。这方面经常让我烦恼,因为你不能只使用:
if ((buff = realloc (buff, newsize)) == NULL)
return;
如果您想要在您的代码中在失败时释放原件。相反,您必须执行以下操作:
if ((newbuff = realloc (buff, newsize)) == NULL)
free (buff);
return;
buff = newbuff;
当然,我理解在失败时保持原始缓冲区完好无损的基本原理,但我的用例已经出现了足够多的情况,以至于我通常编写自己的函数来处理这种情况,例如:
// Attempt re-allocation. If fail, free old buffer, return NULL.
static void *reallocFreeOnFail (void *oldbuff, size_t sz)
void *newbuff = realloc (oldbuff, sz);
if (newbuff == NULL) free (oldbuff);
return newbuff;
// Attempt re-allocation. If fail, return original buffer.
// Variable ok is set true/false based on success of re-allocation.
static void *reallocLeaveOnFail (void *oldbuff, size_t sz, int *ok)
void *newbuff = realloc (oldbuff, sz);
if (newbuff == NULL)
*ok = 0;
return oldbuff;
*ok = 1;
return newbuff;
C11 标准中的相关部分说明(我的斜体):
7.20.3.4
realloc
函数如果
ptr
是空指针,则realloc
函数的行为类似于malloc
函数 规定的大小。否则,如果ptr
与先前返回的指针不匹配calloc
、malloc
或realloc
函数,或者如果空间已被调用释放 对于free
或realloc
函数,行为未定义。如果记忆为新 对象不能被分配,旧对象没有被释放,它的值没有改变。
【讨论】:
重复条件跳转(在调用free
之前检查一次 NULL
并再次在 free
内部检查)在常见情况下(指针不是 NULL
)成本更高,并且只会有帮助最少在极少数情况下(指针为NULL
)。我会说这是净亏损。
实际上,这是一个很好的观点,@R。主要的情况几乎肯定会有一个非空的old
,所以我的支票并没有真正买那么多。我会摆脱它。
您可能也应该跳过调用realloc
,如果sz==0
则直接调用free(old)
。这是因为对于 realloc
返回 0 的含义存在一定程度的分歧。有些人声称如果内存成功调整为 0 大小并且实现具有 malloc(0)==NULL
,则返回 0(而不是设置 errno
)是合法的,在这种情况下,后续的 free(old)
将是危险的双重释放。我会写函数:void *new=0; if (!sz || !(new=realloc(old,sz))) free(old); return new;
实际上要在realloc
-to-size-zero 上获得安全的“成功”回报,在这种情况下,您可能需要return malloc(1);
...呃......
@R..: 麻烦的是,POSIX 说realloc(ptr, 0)
不能释放ptr
并且不应该使用,但是realloc(3)
说它“相当于free(ptr)
, " 不能失败,因为 free()
是 void
并且无法指示失败。【参考方案2】:
realloc()
返回一个指向新分配内存的指针,该指针适合任何类型的变量对齐,如果请求失败,则可能与ptr
或NULL
不同。如果size
等于0,则返回NULL
或适合传递给free()
的指针。如果realloc()
失败,则原始块保持不变;它没有被释放或移动。
malloc(3)
- Linux man page
【讨论】:
【参考方案3】:没有。如果realloc()
失败,则不会更改之前的缓冲区。
男人
realloc(3)
:
realloc()
返回一个指向新分配内存的指针,这适合 为任何类型的变量对齐,并且可能与ptr
或NULL
不同,如果 请求失败。如果 size 等于 0,则NULL
或适合的指针 传递给free()
被返回。如果realloc()
失败,则保留原始块 原封不动;它没有被释放或移动。
【讨论】:
【参考方案4】:不,不会的。 Realloc 更改增加/减少通过 malloc 或 calloc 分配的动态内存。如果 realloc 在增加内存时失败,它将返回 NULL,但不会更改先前分配的内存。由于 Realloc 从先前分配的内存的基地址计算新的内存分配,它不会对内存执行任何操作
【讨论】:
以上是关于如果失败,realloc 会释放前一个缓冲区吗?的主要内容,如果未能解决你的问题,请参考以下文章
我可以假设调用较小大小的 realloc 会释放其余部分吗? [复制]
realloc() 失败并返回 NULL 时的正确用法是啥?