当我们free()
用C记忆时,为什么那个记忆没有填满零?在打电话时,有没有一种好方法可以确保这种情况发生free()
?
我宁愿不冒险将内存中的敏感数据释放回操作系统......
释放存储器块时将其清零将需要额外的时间.由于大部分时间实际上没有必要,因此默认情况下不会这样做.
如果您确实需要(比如您使用内存来存储密码或加密密钥) - memset()
在释放块之前调用.写一个实用功能链memset()
,并free()
是也不是问题.
C为什么在自由实现中内存没有明确地设置为零.
因为速度快.
因为我们释放了内存后我们如何在释放后将其设置为零.
嗯?
如果你想,当你释放它的内存设置为0,你必须自己做之前你free()
吧.如果您尝试free()
它,它不能保证它没有再次分配.例如,您可以使用memset()
它.
free()
不保证将清除内存,因为C不保证malloc()
将返回初始化内存.无论哪种方式,你必须自己初始化它,它已经分配后,所以没有点在清除它时,它的free()
"d
[编辑:这是试图回答原始海报的问题.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 - 你需要一个指向可修改值的指针,而不仅仅是一个值.
最初的C哲学是将隐含效应保持在绝对最小值. 如果程序员想要在释放指向的内存后将指针归零,那就是程序员应该写的东西. 我们这些经常使用像这样的宏的人:
#define FREE(P) ((void)(free((P)), (P) = NULL))
当然,如果传递的表达方式FREE
有副作用,那么刚开了一大堆蠕虫......
free()不会将内存释放回操作系统 - 它会释放回进程的堆管理器.出于效率原因,它并非零.
当进程分配虚拟内存时,大多数操作系统会将其归为零页面.这可以防止内存从一个进程"泄漏"到另一个进程,并导致像您提到的安全问题.
如果您的进程中有数据不想保留在内存中(例如,用户的密码),则您负责将其清零.Windows为此提供了SecureZeroMemory API.
memset(ptr, 0, size); free(ptr);
我想你想要这个......