C++ 使用void*时如何获取数据而不损坏?

C++ 使用void*时如何获取数据而不损坏?,c++,void-pointers,C++,Void Pointers,我用一个映射来存储任何类型的指针(void*),它被用在一个scope对象中。这里是scope类 class Scope { protected: Scope * parent; MyMap* map; public: virtual void setParent(Scope* p)=0; virtual Scope* getParent()=0; virtual void setOwner(void * owner)=0; virtual

我用一个映射来存储任何类型的指针(void*),它被用在一个scope对象中。这里是scope类

class Scope
{
  protected:
    Scope * parent;
    MyMap* map;
  public:
    virtual void setParent(Scope* p)=0;
    virtual Scope* getParent()=0;
    virtual void setOwner(void * owner)=0;
    virtual void * getOwner()=0;
    virtual Symbol * get(char* name)=0;
    virtual Symbol * get(char* name, Signature * sig)=0;
    MyMap* getMap()const;
 };
有两个类
OrderedScope
DisorderedScope
实现了
Scope

在我的项目中,我试图将所有数据存储为void*,然后检索它们并将它们转换为适当的类型。当我对其类型强制转换一个对象时,我发现一些数据丢失了。这是我得到的一张照片。

只是为了澄清
类的范围。在这个范围内,我存储类型为
Function
s的对象。因此,当我想向其中添加函数时,我应该首先检索package对象,然后使用
add
函数插入新函数

我不知道我是否正确地显示了问题,但我希望如此。
非常感谢您的帮助。

无效指针是一种危险的机制,因为它们会禁用编译器对该指针的类型检查。因此,如果您犯了错误(例如将空指针转换为错误的类型),您不会得到编译时错误,您只会注意到问题是运行时的错误行为,例如数据损坏

因此,为了回答这个问题:如果您想使用void指针并避免数据损坏,您必须非常非常确保当您将void指针强制转换为(SomeType*)时,void指针指向的内存位置实际上包含有效的(SomeType*),而不包含其他内容。特别是,您必须确保您的空指针指向的(SomeType*)仍然有效,并且在创建空指针和尝试强制转换和使用它之间没有被删除/释放。当具有多个超类的类可能具有不同的“this”指针(取决于您将其视为哪个超类),并且强制转换为空指针不会自动为您存储正确的“this”指针时,您还需要注意可能涉及的陷阱(因为编译器不知道哪个“this”)您稍后将感兴趣的指针)

这一切都是可行的,但您的程序的逻辑必须在所有情况下100%正确。要做到这一点,没有捷径可走,只有非常仔细地编写所有代码,研究代码以查找错误,并对其进行彻底测试。valgrind和Purify等代码检查器也可以通过运行代码帮助查找症状并不总是明显的错误


也就是说,上面的评论是正确的——通常有更好/更安全的替代方法来使用void指针。这些替代方案(例如模板和/或公共基类)不太容易出错,因为它们让编译器在编译时为您检测错误,而不是强迫您在运行时逐个查找错误。此外,考虑使用智能指针(例如SysDypPTR),而不是原始指针,因为这样会将处理对象的生命周期卸载到编译器上,编译器可以比手持式代码更可靠、更持久地处理该任务。为什么您将其标记为
yacc
-我在您的问题中没有看到任何与
yacc
相关的内容?任何使用
void*
存储任意项目的解决方案都可能是可疑的设计…您是否尝试过进入
getParent()
getOwner()
的调用以查看它们返回的内容,他们从何处获取数据,以及数据是否已初始化。
0xcdcdcdcd
是一个强有力的指示器,表明您正在从未初始化的变量返回指针值。与此问题无关的一点是:避免使用C类型转换,而是使用reinterpret_cast。虽然我同意C样式转换是邪恶的,但建议将reinterpret_cast作为替换并没有多大好处。要从void*返回到实类型,正确的强制转换为static_cast,这与对void*的隐式转换相反。