简体   繁体   English

强制转换为 void* 并返回后如何删除指针

[英]How to delete a pointer after cast to void* and back

As part of a "message"-class I try to transfer pointers of different types by casting them to void*-pointers and saving them in a wrapper class ("MsgData") that remembers the original type of the pointer.作为“消息”类的一部分,我尝试通过将它们转换为 void* 指针并将它们保存在记住指针原始类型的包装类(“MsgData”)中来传输不同类型的指针。

For example a bool pointer:例如一个布尔指针:

bool* data = new bool;
event.wheel.y < 0 ? *data = false : *data = true;
send("all", this, MSG_MOUSE_SCROLL, MsgData(data));

The compatible Constructor of MsgData is called and the variable is saved as a member of my message class:调用 MsgData 的兼容构造函数并将变量保存为我的消息类的成员:

MsgData():                        type_(NULLPTR),    data_(nullptr)     {}  // Null
MsgData(const bool* data):        type_(BOOL),       data_((void*)data) {}  // Bool
MsgData(const std::string* data): type_(STRING_STD), data_((void*)data) {}  // std::string
// ... etc.

I can cast the pointers back and use them without any errors but when I try to delete them the program crashes:我可以将指针转换回来并使用它们而不会出现任何错误,但是当我尝试删除它们时,程序崩溃了:

~MsgData() {
    switch (type_) {
    case (BOOL):
        if ((bool*)data_)
            delete (bool*)data_;
        break;
    // ... etc.
    }
}

The bool pointer is just an example and the same happens with all other types and classes too. bool 指针只是一个示例,所有其他类型和类也是如此。 The program crashes only when I try to delete the pointer.只有当我尝试删除指针时程序才会崩溃。 Casting them back to their original type and using them is not a problem.将它们转换回原始类型并使用它们不是问题。

I researched the problem and found similar question like this one on StackOverflow but while it seems to be considered bad style to cast a pointer to void* and back I cannot find the reason why the program crashes.我研究这个问题,并发现像类似的问题这一个在计算器上,但同时,它似乎被认为是不好的风格蒙上了指针无效*和背部我找不到原因,程序崩溃。

Well, a better solution to the problem is to use boost::variant (or std::variant ).好吧,该问题的更好解决方案是使用boost::variant (或std::variant )。 Once you start using that, all the headache of deleting and managing type and data will go automatically.一旦你开始使用它,删除和管理类型数据的所有麻烦都会自动消失。 You're not the first to face of a problem of this kind;您不是第一个遇到此类问题的人; many others have faced it, and the solution is available in the form of boost::variant or std::variant .许多其他人都面临过这个问题,解决方案可以通过boost::variantstd::variant的形式获得。

Anyway, since you're developing a solution yourself, here is my advise: construct an appropriate deleter in the constructor itself .. or whenever you know what type of data your class is going to hold:无论如何,由于您自己正在开发解决方案,因此我的建议是:在构造函数本身中构造一个适当的删除器......或者每当您知道您的类将保存什么类型数据时

MsgData()
 : type_(NULLPTR), data_(nullptr)     {} 

MsgData(const bool* data)
 : type_(BOOL), data_((void*)data), deleter_(&deleter<BOOL>) {}      

MsgData(const std::string* data)
 : type_(STRING_STD), data_((void*)data), deleter_(&deleter<std::string>) {}  

where deleter_ is a member:其中deleter_是成员:

std::function<void(void const*)>  deleter_;

and deleter is defined as function template:并且deleter被定义为函数模板:

template<typename T>
void deleter(void const * data) {
   delete static_cast<T const *>(data);
}

Once you have these, your destructor would look like this:一旦你有了这些,你的析构函数看起来像这样:

~MsgData() {
   if (deleter_) {
      deleter_(data_);
   }
}

Hope that helps.希望有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM