这个C ++代码中的错误是什么?

时间:2016-05-24 14:56:04

标签: c++ debugging virtualization

我相信它是C ++,但它可能是C?我看了C ++已经有一段时间了,所以我最终找不到这个bug。我在接受采访时被问到这个问题并且没有答案。我显然没有得到这份工作,但现在我很想找到答案。

#include<iostream>

class Base {
public:
    Base() {
        std::cerr<<"constructing Base " << this << std::endl;
        i = new int;
    }
    ~Base() {
        std::cerr<<"destroying Base " << this << std::endl;
        delete i;
    }
private
    int* i;
};

class Derived : public Base {
public:
    Derived() {
        std::cerr<<"constructing Dervied " << this << std::endl;
        d = new double;
    }
    ~Derived() {
        std::cerr<<"destroying Derived " << this << std::endl;
        delete d;
    }
private
    double* d;
};

int main(int argc, char** argv) {
    using namespace std;
    int ret = 1;
    Base* thePtr = new Derived;
    delete thePtr;
    return ret;
}

提前致谢!

4 个答案:

答案 0 :(得分:7)

Base的析构函数不是虚拟的。这最多会泄漏Derived::d指针。

实际上,通过没有虚析构函数的基类指针删除派生类的指针是未定义的行为(感谢GManNickG)

答案 1 :(得分:2)

您应该将CURRENT_DATE类析构函数标记为SELECT * FROM subscriptions WHERE active_until >= (TIMESTAMPDIFF(DAY, 3, CURRENT_DATE)) AND active_until <= (TIMESTAMPADD(DAY, 1, CURRENT_DATE)) AND status LIKE 'ACTIVE' 。在您的代码Base中,类析构函数不是virtual&amp;基类指针指向Base类对象,因此默认情况下析构函数将被调用virtual类,除非它被标记为Derived。这将泄漏Base类数据成员virtual&amp;的动态分配内存。调用未定义的行为

答案 2 :(得分:2)

让我列一个清单......

  • Base析构函数不是virtual
  • 使用原始指针而不是智能指针
  • 事实上,它根本不需要指针newdelete
  • 因此,它实际上并不需要析构函数。
  • 同样Derived拼写为Dervied
  • ......它不会编译。

答案 3 :(得分:0)

您的基类析构函数应该声明为虚拟,它看起来像 cpp virtual ~Base() { std::cerr<<"destroying Base " << this << std::endl; delete i; }

你可以在http://www.programmerinterview.com/index.php/c-cplusplus/virtual-destructors/

找到它

当您可以通过指向基类的指针删除派生类的实例时,虚拟析构函数非常有用:

  

上面的代码存在一个主要问题:当我们删除basePtr时,根本不会调用“Derive”类的析构函数,

派生对象的构造遵循构造规则,但是当我们删除“b”指针(基指针)时,我们发现只有基本析构函数被调用。但是这不能发生。

要做适当的事情,我们必须使基础析构函数成为虚拟的。它类似于运行时多态性,因此编译器会发现这是一个基指针,但指向派生类,并为它自动绑定派生类析构函数