开发者社区> 问答> 正文

C++ 关于指针和delete的问题,delete总是报错 ?报错

近期想仔细了解一下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,香菇,求好心人解答,十分感谢!~

展开
收起
爱吃鱼的程序员 2020-06-23 00:14:38 1967 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    第一个问题
    p2=p;
    只是将内存地址复制到p2,系统并不认为p2是一个动态内存,所以无法释放

    这个问题原来还没想过。。。。。mark下,同求高人解答
    自己有个猜想,会不会是只能是申请内存空间的指针p能用delete,p2虽然和p一样,但它可能只有权限访问这段内存空间,却没有权限释放这段内存空间,因为它不知道这段内存空间的具体大小,只是有这段空间的起始地址而已。

    你用的什么编译器,我用vc++gcc都不报错。

    后面的问题我大概知道是什么原因,原因是你申请了一个单位的内存空间,但是你实际赋值的时候使用了4个单位,这样就造成了内存溢出,虽然你在赋值的时候不会报错,但是释放的时候就会出现内存溢出的错误
    如果将你两个函数中申请内存空间的语句int*p=newint改为int*p=newint[4]就不会报错了

    2020-06-23 00:14:54
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
使用C++11开发PHP7扩展 立即下载
GPON Class C++ SFP O;T Transce 立即下载
GPON Class C++ SFP OLT Transce 立即下载