当前位置:  开发笔记 > 编程语言 > 正文

为什么free()在释放之前没有将内存清零?

如何解决《为什么free()在释放之前没有将内存清零?》经验,为你挑选了7个好方法。

当我们free()用C记忆时,为什么那个记忆没有填满零?在打电话时,有没有一种好方法可以确保这种情况发生free()

我宁愿不冒险将内存中的敏感数据释放回操作系统......



1> sharptooth..:

释放存储器块时将其清零将需要额外的时间.由于大部分时间实际上没有必要,因此默认情况下不会这样做.

如果您确实需要(比如您使用内存来存储密码或加密密钥) - memset()在释放块之前调用.写一个实用功能链memset(),并free()是也不是问题.


实际上,memset并不总是足够的.memset通常是编译器内在的,如果编译器确定您不再使用数据,则可以将其删除(对于对free()的调用可能不会发生这种情况,但对于堆栈上的缓冲区则完全可能).Windows提供SecureZeroMemory功能,不会对其进行优化.更多信息:https://www.securecoding.cert.org/confluence/display/cplusplus/MSC06-CPP.+Be+aware+of+compiler+optimization+when+dealing+with+sensitive+data

2> maykeye..:

C为什么在自由实现中内存没有明确地设置为零.

因为速度快.

因为我们释放了内存后我们如何在释放后将其设置为零.

嗯?



3> Nathan Fellm..:

如果你想,当你释放它的内存设置为0,你必须自己做之前free()吧.如果您尝试free()它,它不能保证它没有再次分配.例如,您可以使用memset()它.

free()不保证将清除内存,因为C不保证malloc()将返回初始化内存.无论哪种方式,你必须自己初始化它,它已经分配后,所以没有点在清除它时,它的free()"d



4> Steve Jessop..:

[编辑:这是试图回答原始海报的问题.shog9的编辑可能会或可能没有改变这个问题 - 由于原版不清楚而很难说...

如果你的意思是,正如其他人所假设的那样,为释放的内存块的每个字节设置0,那么在释放块之后就不能这样做了.尝试这样做会产生未定义的行为.所以,如果你这样做,那么你就会严重误解内存分配.

但我猜你说"我们在释放后将它设置为零",你可能会谈论这样的代码:

free(ptr);
ptr = NULL;

如果是这样,那么free的原因不能将ptr设置为NULL,那就是free只接收来自变量ptr的值.它没有办法修改ptr,因为你没有将变量ptr本身传递给free.您只是传递当前存储在其中的地址.这是C语言设计的一部分 - 当你调用一个传递值的函数时,被调用者无法告诉该值是如何计算的,或者调用者的代码中可能包含哪个变量.即使有可能,对这个语言规则的例外是免费的也是疯狂的.

在任何情况下,并不是每个人在释放它们之后都会将指针归零.有些人认为这是一个很好的安全措施,其他人则认为不是.无论你如何看待它,代码都不会将内存归零,它只会将指针归零到内存.如果你想编写一个为你清除指针的函数,那么你可以:

void free_and_clear(void **pptr) {
    free(*pptr);
    *pptr = NULL;
}

然后像这样使用它:

free_and_clear(&ptr);

请注意,这会传递指向变量ptr的指针,而不是ptr的值.所以free_and_clear可以修改ptr.但是这会对你如何使用它的一些限制不适用于free - 你需要一个指向可修改值的指针,而不仅仅是一个值.



5> Norman Ramse..:

最初的C哲学是将隐含效应保持在绝对最小值. 如果程序员想要在释放指向的内存后将指针归零,那就是程序员应该写的东西. 我们这些经常使用像这样的宏的人:

#define FREE(P) ((void)(free((P)), (P) = NULL))

当然,如果传递的表达方式FREE有副作用,那么刚开了一大堆蠕虫......



6> Michael..:

free()不会将内存释放回操作系统 - 它会释放回进程的堆管理器.出于效率原因,它并非零.

当进程分配虚拟内存时,大多数操作系统会将其归为零页面.这可以防止内存从一个进程"泄漏"到另一个进程,并导致像您提到的安全问题.

如果您的进程中有数据不想保留在内存中(例如,用户的密码),则您负责将其清零.Windows为此提供了SecureZeroMemory API.



7> 小智..:
memset(ptr, 0, size);
free(ptr);

我想你想要这个......


它可用于存储密码和加密密钥的缓冲区http://stackoverflow.com/questions/786093/does-using-securezeromemory-really-help-to-make-the-application-more-secure
推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有