对于反序列化过程,我编写了一个基类,它根据序列化数据变异为派生类。为实现这一目标,我正在使用placement new运算符。一切正常,直到我尝试删除实例。我尝试了不同的方法,但每次都会出现堆损坏错误。我创建了一个简化的示例代码,显示了我的方法。
我正在使用Visual Studio 2010。
以下是展示问题的小样本代码:
Header.h
#pragma once
#include <type_traits>
class BaseClass
{
private:
int _someValue;
BaseClass(const BaseClass &other); // remove copy constructor
BaseClass(BaseClass &&other); // remove move constructor
BaseClass &operator=(const BaseClass &other); // remove assignment operator
public:
BaseClass(void);
virtual ~BaseClass(void);
void ChangeType(bool b);
};
template<typename T>
class DerivedClass : public BaseClass
{
private:
T _someMoreData;
DerivedClass(const DerivedClass &other); // remove copy constructor
DerivedClass(DerivedClass &&other); // remove move constructor
DerivedClass &operator=(const DerivedClass &other); // remove assignment operator
public:
DerivedClass(void) :
_someMoreData(0)
{
static_assert(std::is_same<T, int>::value || std::is_same<T, long>::value, "DerivedClass must be used with 'int' or 'long'.");
}
virtual ~DerivedClass(void)
{}
};
Source.cpp
#include <stdio.h>
#include <memory>
#include <tchar.h>
#include "Header.h"
BaseClass::BaseClass() :
_someValue(0)
{}
BaseClass::~BaseClass()
{}
void BaseClass::ChangeType(bool b)
{
this->~BaseClass();
if (b)
new (this) DerivedClass<int>();
else
new (this) DerivedClass<long>();
}
int _tmain(int argc, _TCHAR* argv[])
{
BaseClass *pBC = new BaseClass();
DerivedClass<int> *pDC = nullptr;
pBC->ChangeType(true);
pDC = reinterpret_cast<DerivedClass<int> *>(pBC);
// work with pDC ...
// 1st try:
delete pBC; // ERROR: Heap Corruption
// 2nd try:
pBC->~BaseClass();
::operator delete(pBC); // ERROR: Heap Corruption
// 3rd try:
pDC->~DerivedClass();
::operator delete(pDC); // ERROR: Heap Corruption
return 0;
}
错误讯息:
HEAP CORRUPTION DETECTED: after Normal block (#111) at 0x004D6970.
CRT detected that the application wrote to memory after end of heap buffer.
我该如何以干净的方式删除这些实例?