2011-09-01 7 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 일지라도 실제로는 초기화 할 수 없습니다.

bufferHeader 개체를 구성하려면 placement new을 사용해야합니다.

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

+1 충돌 가능성이 높습니다. 그러나 Virtual Function Table 자체는 공간을 차지하므로 헤더의 처음 몇 필드를 덮어 씁니다. 이 응용 프로그램에서 가상 상속을 사용하지 않는 것이 가장 좋습니다. –

+0

새로운 배치로 인해 액세스 위반이 수정되었지만 struct에서 vTable의 영향을 고려하지 않았습니다. 중대한 응답, 감사합니다! – bporter

+0

@Amardeep 가상 함수 테이블은 각 인스턴스에 상주하지 않습니다. 가상 함수 포인터를 의미합니까? 어쨌든 나는 그가'sizeof HeaderTypeX'에 의해'offset'을 갱신한다고 가정합니다. 저의 답변에서 다루지 않은 정렬 문제도 있습니다. BTW 이것은 가상 상속이 아닙니다. – Motti