为什么这不是内存泄漏?或者是吗?删除没有虚拟析构函数的基类指针

dte*_*ech 0 c++ inheritance memory-leaks virtual-destructor

我一直在干涉,用英特尔Inspector测试内存泄漏,当我注意到一些不应该的东西时.我继承了std :: vector,它不应该有一个虚拟的析构函数,我在派生类中有一个额外的成员,我在它上面做动态内存分配,在main我在堆上创建一个派生类,强制转换为基类,调用删除...并且没有检测到内存泄漏??? 根据所有逻辑,我应该得到内存泄漏.

template <typename T>
class DynamicArray : public std::vector<T> {
public:    
    DynamicArray() : children(nullptr) {
        children = new int(50);
    }
    ~DynamicArray() {
        if (children) delete children;
    }
    DynamicArray& operator<<(const T& value)
    {
        push_back(value);
        return *this;
    }
private:
    int *children;
};


int main() {
    DynamicArray<int> *pArray = new DynamicArray<int>;
    (*pArray) << 4 << 5;
    static_cast<std::vector<int>*>(pArray);
    delete pArray;
}
Run Code Online (Sandbox Code Playgroud)

Kil*_*nDS 7

pArray仍然是类型DynamicArray<int>和wiil调用正确的析构函数,这可能会泄漏:

std::vector<int>* wrong = static_cast<std::vector<int>*>(pArray);
delete wrong;
Run Code Online (Sandbox Code Playgroud)

编辑:正如Ben Voigt正确提到的,这个最后的代码片段实际上是未定义的行为,因为析构函数std::vector不是虚拟的.所以甚至不能保证这会泄漏

  • 它是未定义的行为,可能比内存泄漏更具灾难性. (7认同)
  • 根据标准,通过指向没有虚拟析构函数的基类的指针删除对象是未定义的行为. (2认同)
  • "在第一个替代方法(`delete`*object*)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义." 5.3.5p3 (2认同)

Ben*_*igt 5

这个表达式没有副作用:

static_cast<std::vector<int>*>(pArray);
Run Code Online (Sandbox Code Playgroud)

在你的代码中,deletenew实际上完全匹配.


此外,此行分配一个int,因此您可能不会在内存分析中注意到它:

children = new int(50);
Run Code Online (Sandbox Code Playgroud)