我怀疑:
void *a = malloc(40);
free(a);
如果我认为malloc(40)分配40个字节的内存并返回该内存的地址然后释放(a)释放/释放该内存但是对于驻留的位模式没有做任何事情在那个记忆中。所以,据说这个相同的内存被分配来说出void * b,然后打印b指向的地址的值给了我相同的值,它给了我一个垃圾值,为什么?
答案 0 :(得分:5)
我认为你有这种情况:
void * a = malloc(40);
free(a);
void * b = malloc(40);
assert(a == b);
这当然是完全合理的,因为记忆很可能会重复使用。
但是,自a == b
以来,您已回答了自己的问题:b
的值与a
的值相同!
我相信您提出了错误的问题,并且您实际上对比较b
指向的内存感兴趣。那是一个完全不同的鱼。两个malloc
电话之间可能发生任何事情。没有任何保证。 malloc
调用的返回值指向的内存是未初始化,并且您无法对其内容进行任何假设。按理说,在典型的优化C库中,内存不会发生变化,但并不能保证。 “安全”运行时环境可能会选择使用特定测试模式覆盖释放或分配的内存,以便更好地检测无效访问。
答案 1 :(得分:3)
它可以给你任何价值 C / C ++标准并未强制要求任何特定的值。在技术术语中,任何未初始化的变量/内存的值都是不确定。
简而言之,您的程序不应该依赖于此值是否具体,如果确实如此,那么它是不可移植的。
答案 2 :(得分:0)
它没有任何保证。您从 malloc 获得的打印块可能会打印以前的数据,也可能不打印。有很多东西可以改变下一个malloc块(所以下一个地址会有所不同)或改变旧的内存块本身。
答案 3 :(得分:0)
free会经常修改你正在释放的内存。
这是一个常见的技巧,特别是在调试模式下,可以用一些固定的模式自由覆盖内存,以便更容易判断你是否双重释放内存,或只是操纵释放的内存。
同样,malloc可能会使用不同的模式覆盖内存,以显示内存未被初始化。
答案 4 :(得分:0)
malloc和free是C风格的内存管理而不是C ++。 C ++替代品是新的和删除操作符。至于free()之后存储在内存中的位模式,是的,它是相同的位模式。如果要手动删除位模式,可以使用memset()或ZeroMemory()编写WinApi代码。
答案 5 :(得分:0)
它将为您提供一些垃圾值,因为函数 free()会将指定的字节设置为某种模式,这将使内存知道字节被释放和未初始化。话虽如此,您将遇到问题中定义的案例是非常不可能且非常不可能的。即使你再次分配相同的字节,相信我,你绝不会认出它们:-)
AFAIK, free()通常使用Visual Studio 将内存设置为 0xFE 0xEE,这大致意味着已分配内存但现在已释放。这些值称为 Sentinel值,这意味着堆仍由进程拥有但未使用。从进程中释放的内存将显示“?? ??”。
答案 6 :(得分:-1)
首先,代码不是c ++而是普通c。
原因是,free()
/ delete
存在,因此系统可以注意内存区域再次可用于分配。
为什么要做任何事情?
然而,这是一个安全问题。我相信一些面向安全的现代系统在将内存提供给应用程序之前会将内存归零。然后,如果您第一次使用malloc()
,则会获得相当于calloc的内容。从来没有,如果你碰巧释放内存然后再分配它可能能够读取你自己的数据。
这种行为的原因很简单。归零内存非常耗时,您可以手动完成。实际上它有O(n)
复杂性。如果你写一个重用它的记忆的数字计算器,你不关心你在malloc()
之后得到什么,因为很可能你应该覆盖它,并且你绝对不希望你的FLOPS受到不必要的负面影响{ {1}}在致电memset()
时。{/ p>
如果您想确保在致电free()
后没有任何内容可以读取内存,则需要在致电free
之前使用memset(a, 0, SIZE)
。