C++ 由\u align\u malloc分配的对齐内存不会由\u Aligned\u free函数释放
int main() {C++ 由\u align\u malloc分配的对齐内存不会由\u Aligned\u free函数释放,c++,pointers,memory-management,malloc,delete-operator,C++,Pointers,Memory Management,Malloc,Delete Operator,int main() { int*对齐 //对齐值0xCCCC{???} 对齐=(int*)_-aligned_-malloc(sizeof(int)*1000,16) //对齐值0x001d9490{-84215041} _已对齐\未对齐(已对齐) ////对齐值0x001d9490{-17891602}地址未更改 *对齐==100 int*y //y值0xCCCC{???} y=新的int() //y值0x001d9480{0} 删除(y) //y值0x00008123{???}地址已更改
为什么第4行的代码没有给出异常?这是否意味着内存没有被_aligned _free正确释放?如果是,那么我们应该如何释放由_aligned _malloc分配的内存。第4行的代码没有做任何事情-您在该行上使用的是
==
(平等测试)而不是=
(分配)。实际上,它正在做一些事情——它将尝试从您刚刚释放的内存块中读取地址(并将该值与100进行比较)。这可能不一定会导致异常-许多堆管理器将从进程地址空间中分配的较大块中分割出块,因此释放块很可能只是将块标记为可供堆管理器重用。释放后读取/写入此空间可能不会每次都导致异常(因为它可能仍然是进程的有效堆空间的一部分),但这肯定是一个错误
另外,在调用\u aligned\u free
之后,指针值(aligned
)不应该改变-这并不意味着内存没有被释放
int*对齐
//对齐值0xCCCC{???}
您没有初始化指针,因此它得到了main
启动之前存在的任何垃圾值。Doint*aligned=NULL代码>如果希望它以null开头
对齐=(int*)_-aligned_-malloc(sizeof(int)*1000,16)
//对齐值0x001d9490{-84215041}
看起来不错
_已对齐\未对齐(已对齐)
////对齐值0x001d9490{-17891602}地址未更改
free
调用都不会更改传入的指针。永远
*对齐==100
正如弗拉斯尼安所指出的,这做了一个比较,并丢弃了结果。但即使您将其更改为赋值,也会取消对已释放指针的引用,这是未定义的行为。这意味着任何事情都可能发生:它可能工作,它可能崩溃,它可能做一些意想不到的事情
int*y
//y值0xCCCC{???}
同样,未初始化
y=新的int()
//y值0x001d9480{0}
好的,您有一个指向int
的指针
删除(y)
//y值0x00008123{???}地址已更改
这是出乎意料的。可能是编译器的一个功能。可能是重用寄存器的优化
*y=100;//破例
因为您取消了对已删除指针的引用,并且再次处于未定义的行为区域。显然,您的平台不喜欢整数的奇数地址。并非所有平台都会在这里抛出异常
规则是传递给free
或delete
的指针不见了。死去的一个退伍军人。把小雏菊往上推。渴望峡湾。不再是了
寄存器中可能有剩余值,但该值不再有效,不应使用。编译器无法捕获您试图使用死指针的情况。在情况1和5中,您正在读取未初始化的值,这是一个错误。在案例4和案例8中,您正在读取释放的内存,这是一个bug。“为什么有缺陷的代码不能达到我的预期”的一般答案是“这就是为什么我们要修复缺陷,有缺陷的代码不能达到你的预期,修复缺陷,代码就能达到你的预期”。谢谢David。我明白你的意思,这些是应该修复的bug。我对这个问题的意图是,为什么对齐(在_aligned_free之后)指向的内存没有设置为无效内存,而在y的情况下(在delete之后)设置为无效内存。在我看来(阅读注释后),它更像是一种编译器或堆deallocator。我只是想确认一下。就这样,谢谢弗拉斯尼安。我得到了这样一个观点:如果没有例外,内存总是由_aligned _free释放的。