C++;:删除此项;返回x; 我对一些C++行为感到好奇,因为如果这个行为是一致的,那么我的代码将从简单性上受益匪浅。基本上,这个想法是让我的对象a中的一个特定函数计算返回float的复杂计算,但就在返回float之前,偶尔调用删除此

C++;:删除此项;返回x; 我对一些C++行为感到好奇,因为如果这个行为是一致的,那么我的代码将从简单性上受益匪浅。基本上,这个想法是让我的对象a中的一个特定函数计算返回float的复杂计算,但就在返回float之前,偶尔调用删除此,c++,free,C++,Free,1 下面是我试图验证的功能一致性的代码示例 #include <iostream> #include <stdio.h> #include <cstdlib> using namespace std; struct A { float test(float a) {delete this; return a;} }; int main() { A *a = new A(); cout << a->test(1.f

1

下面是我试图验证的功能一致性的代码示例

#include <iostream>
#include <stdio.h>
#include <cstdlib>

using namespace std;

struct A
{
    float test(float a) {delete this; return a;}
};

int main()
{
    A *a = new A();
    cout << a->test(1.f) << endl;
    cout << "deleted?" << endl;
    cout << a->test(1.f) << endl;
}
我想这意味着对象被正确删除了(内存中还剩下什么?一个不可调用的框架?一个类型化指针?一个空指针?)。如果是这样,这种行为是否会保持一致(我的函数将只返回本机类型(浮动))


2

此外,我很好奇为什么这似乎不起作用:

struct A
{
    float test(float a) {delete this; return a;}
};

int main()
{
    A a;
    cout << a.test(1.f) << endl;
}


注意请不要在回复中列出一长串解释,解释为什么这是不好的编码/礼节或其他,不要在意,我只是对可能性感兴趣。

成员函数调用
删除此项是安全的
如果您知道该对象是使用标量
new
分配的,并且之后不会有其他任何东西使用该对象

在第一个示例中,在第一次调用
a->test(1.f)
之后,
a
成为一个“悬空指针”。当您第二次取消对未定义行为的引用以调用
test
时,将调用该行为


在第二个示例中,
删除此项语句是未定义的行为,因为对象不是使用
new

创建的。行为是未定义的,但在典型的现代实现中,访问释放内存的实际“可能性”包括(但不限于):

  • delete
    在运行时库级别(RTL)释放内存,但不会将其返回操作系统。即,操作系统级内存保护未启用,并且操作系统继续将该内存视为已分配。但是,存储在释放内存块中的内部RTL数据会破坏您的数据。结果:通过指针访问不会导致代码崩溃,但数据看起来毫无意义(被破坏)

  • 与1相同,但内部RTL数据不会与关键数据重叠。代码不会崩溃,并继续工作“好像”一切都“很好”

  • delete
    向操作系统释放内存。操作系统级内存保护已启用。任何通过指针进行访问的尝试都会立即导致崩溃

  • 您的示例按照第二种情况进行,即,即使在释放内存后,存储在对象中的数据仍保持不变


    您在代码中观察到的崩溃是因为RTL检测到双重
    free
    尝试(或尝试
    free
    非动态内存,如第二个示例所示),这有点超出了您问题的上下文

    删除此项有它的用途,但通常不是一个好主意。删除指针后使用指针会导致未定义的行为。它肯定不会是“一致的”。同样,尝试删除未使用
    new
    分配的内存。如果您的问题只是“此崩溃是否一致?”那么从技术上讲,答案是“否”,这是未定义的行为。但是在实践中,在堆栈分配的对象上调用
    删除这个
    并没有什么好处,只是不清楚你在问什么。您的代码完全被破坏了,但您不希望别人告诉您这些。@user2255757:那么,您的问题是关于什么的?访问释放的内存?或者在本地内存上执行非法的
    删除
    (重复的
    删除
    删除
    )?您提出的问题似乎针对这两个问题,但实际上它们是完全独立的,彼此无关。@user2255757-不是以任何可移植的方式。如果你发现自己需要这样做,那么你已经“做错了”,从设计角度来说。我只想成功地打电话给first a->Test谢谢你不仅仅是认真地回答问题,所以基本上我担心我会被所谓的悬垂所困扰pointer@user2255757 “我只想成功调用first a->test”为什么你不首先这样做?你的用例是什么?@user2255757:你对
    a->test()
    的调用已经像以前一样成功了。但是你在这些调用中所做的是导致你的代码崩溃的原因。不,没有办法让double free“成功”。
    struct A
    {
        float test(float a) {delete this; return a;}
    };
    
    int main()
    {
        A a;
        cout << a.test(1.f) << endl;
    }
    
    *** Error in `./test': free(): invalid pointer: 0xbe9e4c64 *** Aborted (core dumped)