我可以确定重新分配更少的内存总能找到足够的内存吗?
Posted
技术标签:
【中文标题】我可以确定重新分配更少的内存总能找到足够的内存吗?【英文标题】:Can I be sure that reallocating less memory will always find enough of it? 【发布时间】:2021-11-06 22:17:57 【问题描述】:假设我只有malloc
ed x
字节的内存,在对它们做了一些事情之后,我想realloc
y < x
字节。我可以做到这一点,同时确保我的realloc
会找到足够的内存吗?例如,
int *p = malloc(10);
if (p != NULL)
// Do something with `p`.
int *p_ = realloc(p, 5);
// Keep doing something else.
我是否应该确保p_
不是NULL
,即使我重新分配的内存比原来的少?我认为*alloc
函数在请求的内存超过可用内存时返回NULL
,之前的代码可以安全使用吗?
【问题讨论】:
由于realloc
被记录为能够失败,您当然应该始终检查返回值。它会在你的场景中失败吗? - 可能不会,但不能保证。
"我应该确保 p_ 不为 NULL"。是的你应该。为什么要冒险?它不太可能失败,但不能保证它不会。
你必须检查 NULL
【参考方案1】:
我可以确定重新分配更少的内存总能找到足够的内存吗? 我可以做到这一点,同时确保我的 realloc 会找到足够的内存吗?
不,realloc(p, 5);
可能会失败并返回 NULL
。
即使我重新分配的内存比原来的少,我是否应该确保 p_ 不为 NULL?
是的,代码,缩小尺寸时返回NULL
,可以继续使用旧值指针 - 它仍然有效。
int *p_ = realloc(p, 5);
if (p_)
p = p_;
else /* if new_size <= old_size and new_size > 0 */
; // Simply continue with the old `p`, it is still good.
// Do something with `p`.
…
free(p);
注意:这个else
路径通常很难测试。
我认为 *alloc 函数在请求的内存超过可用内存时返回 NULL,之前的代码可以安全使用吗?
不要假设。 realloc()
可能会返回 NULL
,如果新尺寸更大、相同或更小。
设计考虑:
当大小减小时在realloc()
上返回NULL
是合理的,前提是 1) 满足内存句柄 的数量(系统可能只允许这么多分配)并且calloc()
可以暂时需要另一个。 2) 新的大小为0。*alloc(0)
上的返回值细节有历史,有点争议,这里不再讨论。
在任何情况下,只要新大小大于零,NULL
的返回就意味着某个资源在末尾。 Occam's razor 建议代码继续进行与 calloc()
由于大小增长而返回 NULL
时相同的错误处理。
【讨论】:
我需要针对谁的标准库提交错误?如果你因为没有竞技场手柄而无法缩小规模,请不要说你做到了。 @Joshua “我需要针对谁的标准库提交错误?” --> 没有错误。 C 规范允许返回NULL
。明确“代码......可以继续使用旧值指针”不是建议 - 只是一个编译选项。后面的“进行相同的错误处理”是。
此时这是一个兼容性约束。我见过太多假设缩小总是有效的代码。
@Joshua 这个答案并不假定收缩总是有效的。这个答案你发现兼容性限制或错误吗?
我发现大多数知道它正在缩小缓冲区的代码都不会检查并假设 realloc() 成功。为堆块(包括空闲堆块)设置单独句柄的想法是不自然的。以上是关于我可以确定重新分配更少的内存总能找到足够的内存吗?的主要内容,如果未能解决你的问题,请参考以下文章
为啥尽管我在变量中使用 malloc 分配更多内存,但当我打印变量的大小时,它仍然显示更少的内存/字节? [复制]