近期想仔细了解一下C++里的指针、内存分配的问题,所以想验证一下,当一个指针被delete之后的内存会发生什么,所以想尝试一下:
int main() {
int *p = new int;
int *p2;
p2 = p;
delete p2;
system("pause");
return 0;
}
执行delete p2时报错,HEAP CORRUPTION DETECTED:after a normal block....
但是如果把delete语句删掉,会在程序结束的时候报错:内存访问冲突。
不是很能理解为什么。
逻辑上:
给p分配了一个int的内存,p指向这个内存。然后p2 = p,p2也可以指向这个内存。然后delete p2,释放p2指向的内存。
我想过可能的错误:p和p2指向了同一个内存,在释放的时候会产生混乱。但是,为什么会产生这个混乱?p2释放之后,p顶多变成野指针吧(我是这么想的。
然后我把delete p2删除之后,在程序结束的时候,会报一个访存冲突的错误。我想是不是因为p和p2指向同一个内存,在程序结束的时候释放内存,会重复释放,因此报错。于是我改成:
int main() {
int *p = new int;
int *p2;
p2 = p;
p = p + 1;
//delete p2;
system("pause");
return 0;
}
但是依旧报错。
不是很懂了。求好心人帮忙看看~
第二天再运行一遍就好了。我也不是很懂了orzz。但是还有新的问题,见下:
----------------------------------华丽分割线-------------------------------------
其实最原始我的本意是想看看,给一个指针分配一块内存,delete后会发生什么。所以写了如下:
#include<iostream>
#include<string>
using namespace std;
int* InitIntWithoutDelete() {
int *p = new int;
cout << "initwithoutdelete.p:" << p << endl;
for (int i = 0; i < 4; i++) {
p[i] = i;
}
int *p2 = p;
return p;
}
int* InitIntWithDelete() {
int *p = new int;
for (int i = 0; i < 4; i++) {
p[i] = i;
}
int *p2 = p;
delete p2;
return p;
}
int main() {
int *p;
p = InitIntWithoutDelete();
for (int i = 0; i < 4; i++) {
cout << p[i] << endl;
}
system("pause");
return 0;
}
运行时一直没错,但是程序退出的时候,会报错,中断进去,程序断在xlocale:
~locale() _NOEXCEPT
{ // destroy the object
if (_Ptr != 0)
delete _Ptr->_Decref();
}
感觉是程序结束,回收内存的时候越界或者溢出啥的了。
所以想问:
1.为什么会出现这个现象?错误的地方在哪里呢?
2.说起来,想问一下,像这种,我是通过一个函数,返回了一个指向堆内存的指针,那我要释放这个堆,应该怎么释放呢?都说new和delete最好配对,但是我在函数InitIntWithoutDelete()里面new的指针,因为要是要返回它的值,所以在返回之前没法delete吧,一旦delete了,好像现在C++是会自动把这个指针变成x00008123。那这个new就没法有对应的delete了。我一开始猜想的是在函数外部delete,比如在上面那一段中:
int *p = InitIntWithoutDelete();
delete p;
在delete语句中就会报错。
最后就是别的奇奇怪怪的问题了:
我看程序退出报错,就在system("pause")处设了断点。运行到断点的时候,直接点了“继续”,程序正常退出。
但是后来,就算有断点,退出也依然报错了。
我记得我以前也碰到过,就是
设置断点可以运行,但是去掉断点就越界啥的错误了。为啥?
TAT,香菇,求好心人解答,十分感谢!~