C ++访问冲突

时间:2011-09-01 16:03:58

标签: c++ visual-c++

我正在开发一个现有的数据解析程序,它将一个struct叠加到一个缓冲区上,以便提取值。最近,缓冲区中添加了一种新的数据格式,需要一个新的结构。我将函数抽象为一个公共基类,并定义了一个像这样的新结构:

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

我意识到上面的代码段缺少空指针检查;为简洁起见,我排除了一些逻辑。我已经跟踪了代码,一切似乎都在顺利运行,直到尝试在基类上调用方法。在使用代码时,我还看到成员函数不存在错误。

感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

你好像在buffer使用内存而没有在那里构建一个对象。由于Header是多态的,它包含一个虚拟的表指针,你不能直接初始化它的数据(从法律上来说,即使它是POD你也不能,但你可能会侥幸逃脱它。)

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

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