在Visual Studio运行C++代码时触发is_block_type_valid()断言错误求助
Debug Assertion Failed 问题分析与修复
嘿,我来帮你搞定这个调试断言失败的问题!你的代码里犯了一个C++指针使用的典型错误,咱们一步步拆解:
首先先把你的代码贴出来方便分析:
int main() { int var = 5; int* pPointer1 = &var; int* pPointer2 = new int; if (pPointer2 == NULL) { cout << "Failed." << endl; } pPointer2 = &var; cout << "Pointer1: " << *pPointer1 << endl; cout << "Pointer2: " << *pPointer2 << endl; cout << pPointer1 << endl << pPointer2 << endl; delete pPointer2; pPointer2 = 0; }
问题核心
你这里的关键错误是用delete释放了栈内存:
- 一开始你用
new int给pPointer2分配了一块堆内存,这部分是合法的。 - 但之后你执行了
pPointer2 = &var;,把pPointer2的指向改成了栈上变量var的地址(var是在栈上创建的局部变量)。 - 最后调用
delete pPointer2;时,你试图释放的是栈内存,而C++规则里明确要求:delete只能用来释放通过new(或new[])分配的堆内存,释放栈内存会直接触发调试断言失败,甚至可能导致程序崩溃。
另外还有个小问题:你用new分配的堆内存被pPointer2 = &var;覆盖后,再也没有机会释放,造成了内存泄漏。
修复方案
根据你的需求,有两种正确的修改方式:
方案1:让pPointer2指向栈变量var
如果你的目的是让pPointer2指向var,那之前的new int完全没必要,或者要先释放堆内存再改变指针指向:
#include <iostream> using namespace std; int main() { int var = 5; int* pPointer1 = &var; int* pPointer2 = new int; if (pPointer2 == NULL) { cout << "Failed." << endl; return 1; // 分配失败直接退出,避免后续操作 } // 先释放之前分配的堆内存,避免泄漏 delete pPointer2; pPointer2 = &var; cout << "Pointer1: " << *pPointer1 << endl; cout << "Pointer2: " << *pPointer2 << endl; cout << pPointer1 << endl << pPointer2 << endl; // 注意:pPointer2现在指向栈内存,不需要delete pPointer2 = 0; }
方案2:让pPointer2管理堆内存
如果你的目的是用pPointer2管理一块堆内存,那不要改变指针指向,而是把var的值赋值给堆内存:
#include <iostream> using namespace std; int main() { int var = 5; int* pPointer1 = &var; int* pPointer2 = new int; if (pPointer2 == NULL) { cout << "Failed." << endl; return 1; } // 把var的值赋值给堆内存,而不是改变指针指向 *pPointer2 = var; cout << "Pointer1: " << *pPointer1 << endl; cout << "Pointer2: " << *pPointer2 << endl; cout << pPointer1 << endl << pPointer2 << endl; // 现在释放的是堆内存,完全合法 delete pPointer2; pPointer2 = 0; }
关键注意点
- 永远记住:
delete和new必须一一对应,只能释放堆内存,栈内存由系统自动回收,手动释放会触发错误。 - 当你改变指针指向时,一定要检查原来的指针是否指向堆内存,如果是,先释放再改指向,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Doe
相关产品推荐
相关产品推荐

