int main() {
int * aligned;
//对齐值0xcccccccc {???}
aligned =(int *)_ aligned_malloc(sizeof(int)* 1000,16);
//对齐值 0x001d9490 { - 842150451}
_aligned_free(对准);
////对齐值 0x001d9490 { - 17891602}地址未更改
* align == 100;
int * y;
// y值0xcccccccc {???}
y = new int();
// y值 0x001d9480 {0}
删除(Y);
// y值 0x00008123 {???}地址已更改
* y = 100; //提供例外
}
我的问题:
为什么第4行的代码不会给出异常?这是否意味着_aligned_free没有正确释放内存?如果是,那么我们应该如何释放_aligned_malloc分配的内存。
答案 0 :(得分:0)
第4行的代码没有做任何事情 - 您在该行上使用==
(测试相等)而不是=
(赋值)。好吧,实际上,正在做某事 - 它会尝试从你刚刚释放的内存块中的地址读取(并将该值与100进行比较)。这可能不一定会导致异常 - 许多堆管理器将从进程地址空间中分配的较大块中分割出块,因此释放一个块可能只是将块标记为可供堆管理器重用。在释放后读取/写入此空间可能不会每次都导致异常(因为它可能仍然是进程的有效堆空间的一部分),但它绝对是错误。
此外,在调用_aligned_free
后,指针值(aligned
)不应该更改 - 这并不意味着内存未被释放。
答案 1 :(得分:0)
int * aligned;
//对齐值0xcccccccc {???}
你没有初始化指针,所以在main
启动之前它有任何垃圾值。如果您希望它从null开始,请int *aligned = NULL;
。
aligned =(int *)_ aligned_malloc(sizeof(int)* 1000,16);
//对齐值0x001d9490 {-842150451}
看起来不错
_aligned_free(对准);
////对齐值0x001d9490 {-17891602}地址未更改
free
次调用都不会更改传入的指针。永远。
* align == 100;
正如弗拉斯尼安指出的那样,这进行了比较并将结果抛弃了。但即使您将其更改为赋值,也会取消引用释放的指针,这是未定义的行为。这意味着任何事情都可能发生:它可能会起作用,它可能会崩溃,它可能会发生意想不到的事情。
int * y;
// y value 0xcccccccc {???}
再次,未初始化。
y = new int();
// y值0x001d9480 {0}
好的,你有一个指向int
的指针。
删除(Y);
// y值0x00008123 {???}地址已更改
这是出乎意料的。可能是编译器的一个功能。可能是重用寄存器的优化。
* y = 100; //提供异常
因为您取消引用了已删除的指针,并且您再次处于未定义的行为状态。显然你的平台不喜欢整数的奇数地址。并非所有平台都会抛出异常。
规则是您传递给free
或delete
的指针消失了。死。一个前指针。推高位雏菊。渴望峡湾。它已不复存在。
寄存器中可能还有一个值,但它不再有效,不应使用。不能指望编译器捕获您尝试使用死指针的情况。