删除指向派生类的指针时,为RtlValidateHeap指定的地址无效

时间:2016-03-25 22:58:40

标签: c++ pointers memory polymorphism heap-memory

我在C ++项目中遇到多态问题。我有一个名为 State 的基类,以及一个派生的 TestState 类。我试图从 State 指针调用派生类中的虚函数。调用虚函数,但删除指针时出现以下错误:

Invalid address specified to RtlValidateHeap( 00FF0000, 0018FD74 )

在搜索其他答案后,我已经能够理解这意味着堆已损坏,但我找到的解决方案都没有为我工作。

这是我正在运行的代码:

int main()
{
    TestState test;

    State *state = new State();
    state = &test;

    state->Init();

    delete state; 
}

State.h

#pragma once

#include <iostream>

class State
{
public:
    State();
    virtual ~State();

    virtual void Init();
    virtual void Reinit();
    virtual void Deinit();
};

State.cpp

#include "State.h"

State::State()
{
}

State::~State()
{
    std::cout << "Destroying State!" << std::endl;
}

void State::Init()
{
    std::cout << "Initialized State!" << std::endl;
}

void State::Deinit()
{
}

void State::Reinit()
{
}

TestState.h

#pragma once
#include "State.h"
#include <iostream>

class TestState : public State
{
public:
    TestState();
    ~TestState();

    void Init();
    void Deinit();
    void Reinit();
};

TestState.cpp

#include "TestState.h"

TestState::TestState()
{
}

TestState::~TestState()
{
    std::cout << "Destroying TestState!" << std::endl;
}

void TestState::Init()
{
    std::cout << "Initialized TestState!" << std::endl;
}

void TestState::Deinit()
{
}

void TestState::Reinit()
{
}

删除指针时会调用 State TestState 的析构函数。

提前致谢。

3 个答案:

答案 0 :(得分:2)

因为您正在删除堆栈中的内容。将指针指定给对局部变量的引用时,将指针指定给堆栈中分配的实体。使用&#34;删除&#34;无法删除这是堆变量。此外,您正在泄漏使用新分配的内容。

    TestState test;

    State *state = new State();
    state = &test; //Now it points to the test which is in the stack

    state->Init();

    delete state; //Delete something in the stack. Not good.

这样的事情会更好。

   TestState test;

   State *state = &test;

   state->Init();

答案 1 :(得分:1)

即使您的特定问题的解决方案很容易(即您试图删除堆栈分配的变量,就好像它是堆分配的),我想将我的解决方案发布到我神秘的RtlValidateHeap断言。

事实证明,我正在处理的代码在&#34;运行时库&#34;的项目之间有混合设置。 (在项目属性中,在C / C ++下 - &gt;代码生成)。应用程序具有&#34;多线程调试&#34;,DLL具有&#34;多线程调试DLL&#34;。他们都需要设置相同的东西。

如果混合使用DLL和非DLL运行时库,最终会得到两个独立的堆,并且无法使用另一个运行时库从代码中删除在一个运行时库下分配的对象。你最终得到了神秘的RtlValidateHeap断言。

希望这有助于其他人。

答案 2 :(得分:0)

这是共享指针的作用:) The Cherno在youtube上有一个非常好的Smart Pointer视频。

这应该可以解决问题,将您的主要功能更改为此:

#include "TestState.h"
#include "State.h"
#include <memory>

int main()
{
   {
   std::shared_ptr<TestState> test = std::make_shared<TestState>();
    
   std::shared_ptr<TestState> state = test;

   state->Init();
   }
   //delete state; 
}