C++ 为什么资源在发布后仍然可以访问,并且程序没有崩溃?

C++ 为什么资源在发布后仍然可以访问,并且程序没有崩溃?,c++,C++,内存资源被释放,但这并不意味着它消失了!它只是标记为“空闲内存”,下一次程序中的某些内容试图分配内存时,它可能会得到该内存。所以,是的。。。它还在那里。。。现在。。。但你不应该依赖它,因为你无法预测未来它会发生什么 C++不必费心以某种方式“锁定访问”,甚至只是“擦除”释放的内存,因为这只会占用CPU周期,没有任何实际的好处。在你释放记忆后,无论如何你都不应该去碰它 在函数完成运行后,foo中的my_resource字段(在主函数中声明)仍然可以被解析并获得值1234567。我想知道为什么会这样

内存资源被释放,但这并不意味着它消失了!它只是标记为“空闲内存”,下一次程序中的某些内容试图分配内存时,它可能会得到该内存。所以,是的。。。它还在那里。。。现在。。。但你不应该依赖它,因为你无法预测未来它会发生什么

C++不必费心以某种方式“锁定访问”,甚至只是“擦除”释放的内存,因为这只会占用CPU周期,没有任何实际的好处。在你释放记忆后,无论如何你都不应该去碰它

在函数完成运行后,foo中的my_resource字段(在主函数中声明)仍然可以被解析并获得值1234567。我想知道为什么会这样

这是一种未定义的行为,因此,如果你运气不好,它可能会起作用

在典型的C++实现中,这有很好的机会不会崩溃,因为分配小于页面,分配器不需要将内存返回操作系统。这意味着您的进程仍然能够读取该地址


此外,编译器没有决定将地址用于其他内容,因此碰巧值仍然存在。

“编译器做了不该做的事情”。不,你做了你不该做的事。编译器没有编写无效的程序。是的。编译器只是编译了它。“或者更确切地说,编译器做了它不应该做的事情。”-编译器不负责避免未定义的行为;这就是你的角色。是的,检测到故障,但不是编译器。C++允许你拥有巨大的自由度,包括能够自由地打破规则并进入未定义的行为的能力。这样做是你的责任。如果有人告诉你你的程序会崩溃,他们是天真的。它可能会崩溃。可能不会。它可以做很多事情。这就是UB的本质。
#include <iostream>
#include <string>
using namespace std;
static inline string BoolToString(bool boolean_exp) {
    return boolean_exp? "True" : "False";
}
class Foo {
public:
    explicit Foo(int _size) noexcept : 
        my_resource(new int[_size]) {
        cout << "Foo obj init, at: " << this << ", my_resource at:" << my_resource <<endl;
        my_resource[0] = 1234567;
    }
    ~Foo() {
        cout << "A Foo instance at: " << this << " is finalizing; ";
        cout << "my_resource: " << my_resource << endl;
        delete[] my_resource;
        my_resource = nullptr;
    }

public:
    int *my_resource = nullptr;
};

void function_foo(Foo f) {
    cout << "function_foo() invoked" << endl;
}

int main(int argc, char *argv[]) {
    Foo foo(20);
    function_foo(foo); // I think, foo's copy should released after function_foo() return-ed, my_resource should be nullptr;
    cout << "Is foo.my_resource released?: " << BoolToString(foo.my_resource == nullptr) << endl;
    cout << (*foo.my_resource) << endl;
    return 0;
}
Foo obj init, at: 0x61fdd8, my_resource at:0x1f1e90
function_foo() invoked
A Foo instance at: 0x61fdd0 is finalizing; my_resource: 0x1f1e90
is foo.my_resource released?: False
1234567
A Foo instance at: 0x61fdd8 is finalizing; my_resource: 0x1f1e90