0

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

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

主.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;
}

堆栈.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

堆栈.cpp:

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

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

3 回答 3

2

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

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

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

例如:

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

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

于 2013-01-25T23:09:30.767 回答
0

你得到未定义的行为,这(在这种情况下)仍然有效(可能)由于你只返回一个值的原因。

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

只要您不尝试对该变量(或指针firstnode)执行某些操作,例如将其解释为字符串或其他任何内容,这很可能会工作而不会导致任何直接的问题或错误,因为firstnode仍将指向有效内存,只是不再分配(即“不要使用它”)。

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

于 2013-01-25T23:04:38.740 回答
0

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

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

于 2013-01-25T23:04:54.277 回答