删除调用析构函数但不删除对象?

时间:2013-09-24 19:37:43

标签: c++ pointers memory-management destructor

所以我现在用c ++和指针工作了一年半,我想我让他们成功了。我以前多次调用对象上的删除,实际上删除了对象,或者至少我认为它们已经删除了。

以下代码让我感到困惑:

#include <iostream>

class MyClass
{
public:
    int a;

    MyClass() : a(10) {
        std::cout << "constructor ran\n";
    }

    void method(std::string input_) {
        std::cout << param_ << "\n";
    }

    ~MyClass() {
        std::cout << "destructor ran\n";
    }

};

int main()
{

   MyClass* ptr = new MyClass;

   ptr->method("1");

   delete ptr;

   ptr->method("2.5");

}

此代码输出:

constructor ran
1
destructor ran
2.5

我很困惑为什么它没有抛出任何类型的错误 - 我期待一个内存超出范围异常或类似,但没有。 for循环就在那里,因为有一些隐藏的垃圾收集,尽管据我所知在c ++中没有垃圾收集。

任何人都可以解释一下为什么这段代码有效,或者我的代码出错了,因为它没有给我错误?

4 个答案:

答案 0 :(得分:13)

你误解了delete的作用。所有delete都会调用析构函数,并告诉分配器该内存是空闲的。它不会改变实际指针。除此之外的任何事情都是未定义的。

在这种情况下,它对指向的实际数据没有任何作用。该指针指向它之前指向的相同数据,并且在其上调用方法可以正常工作。但是,这种行为无法保证;事实上,它明确没有具体说明。 delete可以将数据清零;或者分配器可以为其他东西分配相同的内存,或者编译器可以拒绝编译它。

为了提高性能,C ++允许你做许多不安全的事情。这是其中之一。如果你想避免这种错误,最好这样做:

delete ptr;
ptr = NULL;

确保您不会尝试重用指针,并且如果您没有使用未定义的行为,则会立即崩溃。

答案 1 :(得分:7)

ptr->method("2.5") undefined behaviour之后致电delete ptr。这意味着任何都可能发生,包括您正在观察的内容。

答案 2 :(得分:5)

在此代码中:

MyClass* ptr = new MyClass;
ptr->method("1");
delete ptr;
ptr->method("2.5");

您正在访问已被释放的内存,这会产生 未定义的行为 ,这意味着任何事情都可能发生,包括最糟糕的情况:它似乎正常工作

这就是为什么将这样的指针设置为NULL而不是允许发生这种事情的好习惯之一的原因之一:

delete ptr;
ptr = NULL;

尽管最好的办法是尽可能完全避免使用指针。

答案 3 :(得分:0)

您正在访问内存,在其他新呼叫使用之前不会重置。但是每次调用delete时都是一个好习惯,就是将指针设置为NULL。 / p>