近期想仔细了解一下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,香菇,求好心人解答,十分感谢!~
第一个问题
p2=p;
只是将内存地址复制到p2,系统并不认为p2是一个动态内存,所以无法释放
这个问题原来还没想过。。。。。mark下,同求高人解答
自己有个猜想,会不会是只能是申请内存空间的指针p能用delete,p2虽然和p一样,但它可能只有权限访问这段内存空间,却没有权限释放这段内存空间,因为它不知道这段内存空间的具体大小,只是有这段空间的起始地址而已。
你用的什么编译器,我用vc++gcc都不报错。
后面的问题我大概知道是什么原因,原因是你申请了一个单位的内存空间,但是你实际赋值的时候使用了4个单位,这样就造成了内存溢出,虽然你在赋值的时候不会报错,但是释放的时候就会出现内存溢出的错误
如果将你两个函数中申请内存空间的语句int*p=newint改为int*p=newint[4]就不会报错了
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。