我知道在硬盘驱动器上,如果删除文件,数据不会(立即)消失。数据仍然存在,直到被覆盖。我想知道内存中是否存在类似的概念。假设我为一个字符串分配了256个字节,在free()
之后,该字符串是否仍在内存中浮动,直到被覆盖为止?
通常,它确实存在,除非您在free
之前显式覆盖字符串(就像人们有时使用密码一样)。一些库的实现会自动覆盖释放的内存以捕获对其的访问,但是在释放模式下不会这样做。
您的类比是正确的。内存中的数据不会消失或类似的东西;尽管尝试从已释放的内存中进行读取是未定义的行为,但free()
之后的值实际上确实仍然存在。
答案在很大程度上取决于实现。在一个好的实现中,很可能至少内存的开始(或结尾?)会被簿记信息覆盖,以跟踪空闲的内存块,这些内存块稍后可以重用。但是细节会有所不同。如果您的程序具有任何级别的并发性/线程(甚至在您可能看不到的库实现中),那么此类内存可能会被异步破坏,甚至可能甚至读取它也是危险的。当然,free
的实现可能会完全从程序的虚拟地址空间中取消映射地址范围,在这种情况下,尝试对其执行任何操作都会使程序崩溃。
[从应用程序作者的角度出发,您应该仅根据规范对待free
,并且永远不要访问释放的内存。但是从系统实现者或集成者的角度来看,了解(或设计)实现可能会很有用,在这种情况下,您的问题就很有趣。
如果要验证实现的行为,下面的简单程序将为您完成此操作。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* The number of memory bytes to test */
#define MEM_TEST_SIZE 256
void outputMem(unsigned char *mem, int length)
{
int i;
for (i = 0; i < length; i++) {
printf("[%02d]", mem[i] );
}
}
int bytesChanged(unsigned char *mem, int length)
{
int i;
int count = 0;
for (i = 0; i < MEM_TEST_SIZE; i++) {
if (mem[i] != i % 256)
count++;
}
return count;
}
main(void)
{
int i;
unsigned char *mem = (unsigned char *)malloc(MEM_TEST_SIZE);
/* Fill memory with bytes */
for (i = 0; i < MEM_TEST_SIZE; i++) {
mem[i] = i % 256;
}
printf("After malloc and copy to new mem location\n");
printf("mem = %ld\n", mem );
printf("Contents of mem: ");
outputMem(mem, MEM_TEST_SIZE);
free(mem);
printf("\n\nAfter free()\n");
printf("mem = %ld\n", mem );
printf("Bytes changed in memory = %d\n", bytesChanged(mem, MEM_TEST_SIZE) );
printf("Contents of mem: ");
outputMem(mem, MEM_TEST_SIZE);
}