我正在开发一个现有的数据解析程序,它将一个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
我意识到上面的代码段缺少空指针检查;为简洁起见,我排除了一些逻辑。我已经跟踪了代码,一切似乎都在顺利运行,直到尝试在基类上调用方法。在使用代码时,我还看到成员函数不存在错误。
感谢您的帮助。
答案 0 :(得分:5)
你好像在buffer
使用内存而没有在那里构建一个对象。由于Header
是多态的,它包含一个虚拟的表指针,你不能直接初始化它的数据(从法律上来说,即使它是POD你也不能,但你可能会侥幸逃脱它。)
您应该使用placement new
来构建Header
中的buffer
对象。
parsedHeader = new (&buffer[offset]) HeaderTypeA;