如果“u heapchk()返回”,是否可以假定堆没有损坏;好吧;? 在VisualC++中,使用 NeX[]/CODE分配对象数组,然后默认缺省值>代码>删除> /代码>(不是删除[]/COD> >)。 所有对象调用析构函数需要知道对象的数量,因此VisualC++调用“代码>::运算符new []())/>代码分配一个稍微大一些的缓冲区,将元素的数量放在开始,然后调用构造函数并返回指向第一个对象的指针。当删除完成时,它只会销毁第一个对象,然后将错误的指针传递到::operator delete(),默认情况下,该操作的实现方式与::operator delete[]()完全相同
如果出现以下情况:如果“u heapchk()返回”,是否可以假定堆没有损坏;好吧;? 在VisualC++中,使用 NeX[]/CODE分配对象数组,然后默认缺省值>代码>删除> /代码>(不是删除[]/COD> >)。 所有对象调用析构函数需要知道对象的数量,因此VisualC++调用“代码>::运算符new []())/>代码分配一个稍微大一些的缓冲区,将元素的数量放在开始,然后调用构造函数并返回指向第一个对象的指针。当删除完成时,它只会销毁第一个对象,然后将错误的指针传递到::operator delete(),默认情况下,该操作的实现方式与::operator delete[]()完全相同,c++,visual-c++,memory-management,undefined-behavior,C++,Visual C++,Memory Management,Undefined Behavior,如果出现以下情况: class Class { public: ~Class() { Sleep( 0 );} }; delete new Class[1]; 在版本配置中编译,并在调试器下运行。程序以断点停止: ntdll.dll!_DbgBreakPoint@0() ntdll.dll!_RtlpBreakPointHeap@4() + 0x28 bytes ntdll.dll!_RtlpValidateHeapEntry@12() + 0x113 bytes
class Class {
public:
~Class() { Sleep( 0 );}
};
delete new Class[1];
在版本配置中编译,并在调试器下运行。程序以断点停止:
ntdll.dll!_DbgBreakPoint@0()
ntdll.dll!_RtlpBreakPointHeap@4() + 0x28 bytes
ntdll.dll!_RtlpValidateHeapEntry@12() + 0x113 bytes
ntdll.dll!_RtlDebugFreeHeap@12() + 0x97 bytes
ntdll.dll!_RtlFreeHeapSlowly@12() + 0x246cf bytes
ntdll.dll!_RtlFreeHeap@12() + 0x17646 bytes
sample.exe!free(void * pBlock=0x0003339c) Line 110 C
sample.exe!main() Line 48 C++
sample.exe!__tmainCRTStartup() Line 266 + 0x12 bytes C
kernel32.dll!_BaseProcessStart@4() + 0x23 bytes
这看起来像堆损坏-至少这是我在本例中所期望的
我试着在那行之前和之后调用,但令人惊讶的是,它两次都返回\u HEAPOK
。当程序结束时,也不会报告泄漏
如果
\u heapchk()
返回\u HEAPOK
,我是否可以假设堆是完整的?否,\u heapchk返回\u HEAPOK仅仅意味着它找不到问题或者堆不支持验证
我想说的是,当您出现此错误时,更有可能是删除了未初始化的指针。否,\u heapchk returning\u HEAPOK仅仅意味着它找不到问题或堆不支持验证
我想说的是,当出现此错误时,更有可能是删除了未初始化的指针。我不能肯定,但我已经对此进行了一些研究,并注意到两件事:
这就是为什么_heapchk()不会返回失败…我不能肯定,但我已经玩了一点,注意到两件事:
\u heapchk
函数通过检查堆的最小一致性来帮助调试与堆相关的问题
它不会检查绝对的一致性和正确性:它应该能够检测出严重的错误,但它不会捕捉到每一个错误。来自(我的重点):
\u heapchk
函数通过检查堆的最小一致性来帮助调试与堆相关的问题
它不会检查绝对的一致性和正确性:它应该能够检测重大的异常错误,但它不会捕获所有错误。您的意思是,您在调用未定义的行为后调用函数,但仍然希望信任结果?;-) 在这里,我只是猜测,未定义的行为可以在很多方面表现出来,最常见的是“似乎有效”。惊讶 其他异常情况包括:
-在同一语句中调用new和delete。
-您只分配一个元素。
-在整个程序中,您只能在一个位置执行此操作。
-析构函数对内存分配没有任何重要作用。
所有这些都会影响优化器生成代码的方式,正如eran所说,编译器可以很容易地看到所有这些并了解您正在做什么。这并不愚蠢 您的意思是,您在调用未定义的行为后调用了函数,但仍然希望信任结果?;-) 在这里,我只是猜测,未定义的行为可以在很多方面表现出来,最常见的是“似乎有效”。惊讶 其他异常情况包括:
-在同一语句中调用new和delete。
-您只分配一个元素。
-在整个程序中,您只能在一个位置执行此操作。
-析构函数对内存分配没有任何重要作用。
所有这些都会影响优化器生成代码的方式,正如eran所说,编译器可以很容易地看到所有这些并了解您正在做什么。这并不愚蠢