2011-09-01 203 views
3

我正在研究一个现有的数据解析程序,它将一个结构覆盖到一个缓冲区中以提取值。最近一种新的数据格式已被添加到缓冲区,并需要一个新的结构。我抽象功能集成到一个公共的基类,并定义了新的结构是这样的:C++访问冲突

struct Header 
{ 
    Header() { } 

public: 
    virtual unsigned __int8 getCommonField1() const = 0; 
} 

struct HeaderTypeA : public Header 
{ 
    unsigned __int8 Field1; 

public: 
    unsigned __int8 getCommonField1() const { return Field1; } 
} 

struct HeaderTypeB : public Header 
{ 
    unsigned __int8 Field0; 
    unsigned __int8 Field1; 

public: 
    unsigned __int8 getCommonField1() const { return Field1; } 
} 

现有代码它执行处理计算的数据(这是工作),并返回一个指针到调用函数...一些像这样:

Header* parse() 
{  
    Header* parsedHeader = 0; 

    if (typeADetected) 
    { 
     parsedHeader = (HeaderTypeA *) &buffer[offset]; 
     // Other logic here... 
    } 
    else if (typeBDetected) 
    { 
     parsedHeader = (HeaderTypeB *) &buffer[offset]; 
     // Other logic here... 
    } 

    return (parsedHeader); 
} 

问题出现在解析逻辑的调用者。当插头被返回作为一个指针成员函数调用导致访问冲突错误:

Header * hdr; 
hdr = m_parser->parse(); 
unsigned __int8 value = hdr->getCommonField1(); // Access Violation 

我实现上述代码段缺少空指针检查;为了简洁,我已经排除了一些这种逻辑。我已经追踪了代码,并且在尝试调用基类上的方法之前,所有内容都可以顺利运行。在玩代码时,我也看到成员函数不存在错误。

感谢您的任何帮助。

+0

你能告诉我们初始化缓冲区吗? – JaredPar

+0

什么是“缓冲区”? –

+0

不幸的是,这并不容易。缓冲区实际上是作为另一个结构的一部分传递给解析函数的。它的初始化深埋在我不敢触及的一些C++代码的深处。我应该注意到,我简化了上面代码片段的代码。 – bporter

回答

5

您似乎在使用buffer中的存储器而无需在其中构建对象。由于Header是多态的,它包含一个虚拟表格指针,你不能直接初始化它的数据(在法律上你不能,即使它是一个POD,但你可能会逃避它)。

您应该使用placement new以构建buffer中的Header对象。

parsedHeader = new (&buffer[offset]) HeaderTypeA; 
+2

+1这可能是坠机的原因。但是,虚拟功能表本身占用空间,所以他会覆盖标题中的前几个字段。最好不要在这个应用程序中使用虚拟继承。 –

+0

新的位置修复了访问冲突,但我也没有考虑到结构中vTable的影响。很好的答案,谢谢! – bporter

+0

@Amardeep虚拟函数表并不驻留在每个实例中,你的意思是虚拟函数指针吗?无论如何,我假设他用'sizeof HeaderTypeX'更新'offset'。这里也有对齐问题,在我的回答中我没有涉及到。顺便说一句,这不是虚拟继承。 – Motti