가상 함수 테이블이 0을 가리키는 개체에서 가상 함수를 호출하려고하기 때문에 발생하는 응용 프로그램의 액세스 위반을 분석하고 있습니다. 객체의 수명에서 가상 함수 테이블 포인터가 설정되지 않았거나 명시 적으로 0으로 설정된 점은 무엇입니까?가상 함수 테이블이 0으로 설정되는시기는 언제입니까
(우리는 컴파일러로 비주얼 C++ (10)를 사용합니다.)
가상 함수 테이블이 0을 가리키는 개체에서 가상 함수를 호출하려고하기 때문에 발생하는 응용 프로그램의 액세스 위반을 분석하고 있습니다. 객체의 수명에서 가상 함수 테이블 포인터가 설정되지 않았거나 명시 적으로 0으로 설정된 점은 무엇입니까?가상 함수 테이블이 0으로 설정되는시기는 언제입니까
(우리는 컴파일러로 비주얼 C++ (10)를 사용합니다.)
객체가 유효한 상태에있는 동안 vtable에 포인터가 0이되지 않습니다. 생성 및 소멸 중에 객체에 동적 기본 유형의 추상 기본 클래스가있는 경우 vtable은 순수 가상 함수를 포함하는 추상 기본 클래스 vtable을 가리키지 만 vtable 포인터 자체는 여전히 0이 아닙니다.
vtable 포인터가 0 일 수있는 유일한 시간은 생성 전이나 삭제 후입니다.
vtable에 포인터가 진정 제로의 경우, 당신은 같은 VC++ 확장을 사용하고 있습니다 : 어떤 가상 함수가 될 수 없기 때문에,
class __declspec(novtable) Base {
public:
Base();
virtual void proc();
};
다음
__declspec(novtable)
클래스가 vtable에 필요하지 않습니다 컴파일러를 알려줍니다 파생 클래스가 자체 vtable을 설치할 때까지 호출됩니다. 그런 다음 Base :: proc()을 호출하면 오류가 발생할 수 있습니다.
더 가능성이 VTABLE 자체가 비 제로이지만, 함수의 슬롯은 가상 순수되는 인한 기능, 제로 : 다음
class Base {
public:
virtual void proc() = 0;
};
누군가와 함께 어쨌든라는 코드 같은 :
void Derived::proc() {
Base::proc();
// Derived-specific stuff here.
};
이것은 파생물 작성자가 기본 버전이 존재하지 않아도 기본 버전을 호출하는 데 필요한 재정의를 가정했기 때문에 발생할 수 있습니다.
어느 쪽이든,이 방법을 찾는 한 가지 방법은 모든 기본 클래스의 속임수를 중지하고, 함수를 정상적으로 정의하며, 무엇을 호출하는지 확인하는 것입니다. 예 :
class Base {
public:
virtual void proc() {
assert(typeof(*this) != typeof(Base)); // Break-point here.
}
};
어느 쪽도 아니야. 디버거는 명시 적으로 vtable 포인터가 0으로 표시되므로 개별 항목을 표시 할 수도 없습니다. – fschoenm
코드에서 문제를 재현 할 수 있다면 문제를 해결하는 것이 더 쉬울 수 있습니다. 건설중인 물건을 오용하여 UB의 인스턴스가 생겼을 수도 있습니다. –
이것은 잘못된 접근 방식처럼 느껴집니다. 먼저 메모리 디버거를 사용하여 프로그램을 실행하고 무언가를 이중으로 삭제하지 않을 것인지 아니면 그 라인을 따라 무언가를 삭제하는지 확인하십시오. –
불행히도 우리 개발 시스템에서 문제가 발생하지 않기 때문에 분석 할 덤프 파일 만 있습니다. – fschoenm