调用已删除的对象成员后,为什么没有错误?

时间:2013-01-25 22:59:01

标签: c++ delete-operator

我不应该在“main.cpp”第8行收到错误吗?

  • 我没有使用析构函数。
  • 我认为它与“const”关键字有关。

main.cpp中:

#include "stack.hpp"
int main() {
    node* firstnode = new node(NULL, 5);
    std::cout << firstnode -> getvariable() << std::endl;
    node* secondnode = new node(NULL, 10);
    std::cout << secondnode -> getvariable() << std::endl;
    delete firstnode;
    std::cout << firstnode -> getvariable() << std::endl;
    return 0;
}

stack.hpp:

#ifndef stack_hpp
#define stack_hpp
#include <iostream>
class node {
public:
    node(node* nextnode, int variablevalue);
    void setvariable(const int variablevalue);
    const int getvariable() const;
private:
    node* nextnodelink;
    int variable;
};
#endif

stack.cpp:

#include "stack.hpp"
node::node(node* nextnode, int variablevalue)
: nextnodelink(nextnode), variable(variablevalue) {
}

const int node::getvariable() const {
    return variable;
}

3 个答案:

答案 0 :(得分:2)

删除对象时,对象占用的内存将被放回“可用”状态。因此,计算机运行速度很快,“使其可用”的设计是这样的,除了将释放的对象添加到链表或类似的东西之外,它不会做很多事情。例如,它不会用废话填充它以使其变得无法使用。使用C ++的一点是它很快 - 让每个delete填充对象都是无意义的,只是为了确保你以后不能使用它会减慢速度。

当然,可能是,如果你做了一些其他的分配,那么对象的内容确实是“坏的”。这就是它“未定义”的原因。该标准没有说明会发生什么,几乎任何事情都可能发生。计算机着火不大可能,但C标准本身没有任何措辞可以说“它不能导致计算机着火”或类似的任何东西。

一个好的经验法则是,如果要使代码安全,请在删除指针后将其设置为NULL。这样,你的prgram很可能在使用指针时崩溃。

例如:

delete firstnode;
firstnode = NULL;
std::cout << firstnode -> getvariable() << std::endl;

现在,当你调用“getvariable”时,你的程序会崩溃。它并非100%肯定会一直这样做。例如,如果你有一个返回常量的函数,它可能仍然“有效”。

答案 1 :(得分:0)

你正在获得未定义的行为,这是(在这种情况下)仍在工作(可能),因为你只是返回一个值。

在您的情况下,

firstnode->getvariable()只会告诉您的CPU获取存储在firstnode + x的值,其中x只是基于您的类结构的偏移量。

只要您不尝试对该变量(或指针firstnode)执行某些操作,这很可能会在不引起任何直接问题或错误的情况下发挥作用,例如:将它解释为一个字符串或其他什么,因为firstnode仍将指向有效的内存,而不再分配(即“不要使用它”)。

然而,编译器可能会为调试版本(不一定是您的编译器)添加一些开销代码,如果您尝试这样做会导致异常。

答案 2 :(得分:0)

为了获得错误,生成的代码需要跟踪您创建的内容和删除的内容,并检查每次操作是否合法。这不是免费的,但会在时间和空间上产生成本。因此,它没有完成。 C ++通常避免引入会导致运行时开销的检查。

因此,您有责任不引发未定义的行为。