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

Invalid address specified to RtlValidateHeap when deleting pointer to derived class

本文关键字:RtlValidateHeap 地址 无效 指针 派生 删除      更新时间:2023-10-16

我正在处理的C++项目中存在多态性问题。我有一个名为State的基类和一个派生的TestStateclass。我试图从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()
{
}

测试状态.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()
{
}

删除指针时,将调用StateTestState

提前谢谢。

因为您正在删除堆栈中的某些内容。当您将指针分配给对局部变量的引用时,您将指针指定给堆栈中分配的实体。不能使用针对堆变量的"delete"来删除它。此外,你正在泄露你用新分配的东西。

    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();

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

事实证明,我正在处理的代码在"运行库"的项目之间有混合设置(在项目属性中,在C/C++->代码生成下)。应用程序有"多线程调试",DLL有"多螺纹调试DLL"。它们都需要设置为相同的东西。

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

希望这能帮助其他人。

这就是共享指针的用途:)youtube上有一个由The Cherno制作的非常好的智能指针视频。

这应该会解决问题,将您的主要更改为:

#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; 
}