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

Invalid address specified to RtlValidateHeap when deleting pointer to derived class

我在处理的 C++ 项目中遇到多态性问题。我有一个名为 State 的基础 class 和一个派生的 TestState class。我正在尝试从 State 指针调用在派生的 class 中被覆盖的虚函数。调用了虚函数,但是删除指针时出现以下错误:

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

在搜索了其他答案后,我了解到这意味着堆已损坏,但是 none 我找到的解决方案对我有用。

这是我的代码 运行:

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()
{
}

测试State.h

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

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

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

测试State.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();

尽管您的特定问题的解决方案很简单(即您试图删除一个 stack-allocated 变量,就好像它是 heap-allocated),但我想 post 我的解决方案到我神秘的 RtlValidateHeap 断言。

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

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

希望这对其他人有帮助。

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

这应该可以解决问题,将您的主要内容更改为:

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