【发布时间】:2015-09-23 06:27:28
【问题描述】:
在一本 C 书籍中,我在一个实现动态调整大小数组的示例中找到了这段代码(简化):
void *contents = realloc(array->contents, array->max * sizeof(void *));
array->contents = contents;
memset(array->contents + old_max, 0, array->expand_rate + 1);
来源:Learn C The Hard Way – Chapter 34
我有点惊讶memset 应该在这里实现什么,但后来我明白它是用来“清零”重新分配的内存。
我用谷歌搜索了,如果这是我在realloc 之后应该做的事情,并找到了关于这个的 stackoverflow 答案:
可能没有必要做
memset[…]但是,即使您想“将其归零以使一切都很好”,或者确实需要将新指针设为
NULL:C 标准并不保证所有位为零是空指针常量(即NULL),所以memset()无论如何都不是正确的解决方案。
来源:How to zero out new memory after realloc
建议的解决方案是使用for 循环而不是memset,以便将内存设置为NULL。
所以我的问题是,memset 并不一定意味着将值设置为NULL,而for 循环解决方案似乎有点乏味——真的需要设置新分配的内存吗?
【问题讨论】:
-
IMO 这相当于询问
calloc与malloc。如果您使用calloc分配和归零内存,那么如果您需要使用realloc增加缓冲区,那么也使用memset是一致的。 -
我觉得奇怪的是,您读到需要使用 for 循环,将每个值都设置为 NULL 而不仅仅是将内存归零。我认为从技术上讲 NULL 不必等于 0x0。但是,在实践中,您将很难找到不这样做的编译器/系统。 (有人可以备份吗?)
-
根据某些人的说法,Learn C the Hard Way 是not a great resource,我倾向于同意。考虑至少阅读一些其他资源,例如来自this answer SO C 书单。请注意,如果您决定阅读 K&R,请用一只手阅读,另一只手阅读勘误表。
-
@RoyT。 NULL has to compare equal to
0but does not have to be all zero bits,尽管在实践中通常是这样。 -
@RoyT。 - 它发生在一些没有内存保护的旧系统上。物理地址 0 可以包含操作系统信息,例如中断处理程序。写入空指针会覆盖这是一个糟糕的想法。在这种情况下,让 NULL 指向 ROM 而不是 RAM 可能会更好。