2012-04-18 1 views
1

그래서 VS 2008에서 C++로 임베디드 환경 (ARM 프로세서)을 사용하고 있습니다. 내 회사를 위해 중간 크기의 프로젝트를 만들었습니다. 그것은 지금까지 윈도우 응용 프로그램되었습니다. 나는이 응용 프로그램에 더 의미가 있기 때문에 콘솔 응용 프로그램으로 변경하라는 요청을 받았습니다. 나는 창 응용 프로그램을 만들기위한 진짜 이유가 없었습니다 ... 처음에는 방금 VS에서 적절한 설정을 변경하고 다시 작성했습니다. 그것은 잘 만들었지 만, 프로그램을 실행하려고 할 때마다 제목에서 예외가 인용되었습니다. 콘솔 응용 프로그램으로 전환하기 전에 프로그램이 완벽하게 작동하고 있음을 강조하고 싶습니다. 나는 전체 솔루션을 완전히 깨끗하게하고 다시 만들었습니다.정적 STL 집합에 처음 삽입하면 처리되지 않은 예외가 발생합니다. 0xC0000005 : 액세스 위반이 throw됩니다.

나는이 설정이 수동으로 설정을 변경하기 때문에 문제가 될 것이라고 생각했기 때문에 콘솔 앱으로 설정된 새 프로젝트를 만들었고 모든 소스/기타 관련 프로젝트를 그 프로젝트에 연결했습니다. 하나의 솔루션으로 다른 프로젝트를 모두 올바르게 연결하면이 작업이 잘되지만 동일한 오류가 발생합니다.

프로그램 충돌, 그것은 다음과 같은 방법으로 삽입 명령에서 정지

:

template<class Elem> 
Node<Elem>* Node<Elem>::addChild(const Elem& value) 
{ 
    Node<Elem>* newNode = new Node(value); 
    newNode->m_pParentNode = this; 
    m_childList.push_back(newNode); 
    m_sNodeSet.insert(newNode); 
    return newNode; 
} 

m_sNodeSet 트리의 각 노드는 고유해야합니다 규칙을 시행 할 수있다. 오류는이 addChild 메서드가 처음 호출 될 때 발생합니다. 이 시점에서 m_sNodeSet은 크기가 0이고 일부 메모리를 할당해야합니다. 그러나 던져진 예외는 Bad Alloc이 아닌 Access Violation입니다. 삽입 명령문 앞에 m_sNodeSet.get_allocator(). allocate (5)를 추가하여 시도했으나 아무 일도 할 수 있는지 확인했지만 동일한 예외가 발생했습니다. 차이가 나는 경우 m_sNodeSet은 정적 멤버 변수입니다.

이 Node 클래스는 내가 만든 사용자 정의 트리 객체입니다. 나는 몇 주 동안이 나무 프로젝트에서 아무 것도 변경하지 않았으며 잘 작동하고 있습니다. 나는이 트리 프로젝트에서 이전에 보지 못했고 완벽하게 수행 한 것을 던지고 있다고 생각하지 않기 때문에 트리 프로젝트 자체에 문제가 있다고 생각하지 않습니다.

이는 라이브러리 경계를 넘어 STL 컨테이너에 액세스하는 데 문제가되지 않는다는 것을 확신합니다. 이 오류는 단일 정적 라이브러리 조작 중에 발생합니다.

이 작업을 올바르게 수행하려면 솔루션에서 변경해야하는 설정이 있어야합니다. 솔루션에는 여러 개의 프로젝트가 있습니다. 하나는 DLL, 하나는 LIB, 하나는 EXE입니다. 트리는 네 번째 프로젝트이지만 적절한 프로젝트의 "추가 포함"에 간단히 넣습니다. 콘솔 앱으로 실행되도록 EXE 만 변경했습니다.

여기에 문제가 될 수있는 것에 모든 잉크가 묻어 있으면 많은 도움이됩니다.

+0

는 함수에 스테핑 시도? –

+0

다른 정적 구성에서 코드가 호출 될 가능성이 있습니까? m_sNodeSet이 초기화되기 전에? –

+3

이 도움이 되나요 [정적 초기화 순서 대 실패 무엇을?] (http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14) –

답변

1

당신이 선언 한 경우 :

// Global scope 
// > (quote)The m_sNodeSet is a static member variable, 
std::set<Node<Elem>*> Node<Elem>::m_sNodeSet; 

개인 참고 : 접두사 m_은 일반적으로 멤버 변수 (안 정적 멤버)의 기부자이다. 따라서이 접두사를 사용하여 많은 사람들을 혼동하게됩니다.

m_sNodeSet는 정적 멤버 위의 코드는 다음 잠재적으로 초기화 순서에 문제가 주요 전에 을 실행중인 경우. 이것은 해결하기는 쉽지 않습니다 (아래 참조). 그렇지 않으면 메모리 손상이 발생합니다.

class Node 
{ 

    // Remove this line 
    // static std::set<Node*> m_sNodeSet; 
    // Replace with this code 
    static std::set<Node*>& getNodeSet() 
    { 
     static std::set<Node*> sNodeSet; 
     return sNodeSet; 
    } 
    // Replace all references to m_sNodeSet with getNodeSet() 
} 

이 때문에 가변 sNodeSet 정적 따라서 처음 사용할 때 생성되고, 프로그램의 길이 살아 남아 getNodeSet()있어서 내부 작동한다. 각 호출은 동일한 객체에 대한 참조를 반환합니다. 첫 번째 호출에서 만들어 지므로 사용 지점으로 반환 될 때 살아 있는지 (그리고 완전히 구성되었는지) 확인됩니다.

+0

그것은 작동합니다! 그러나 정확히 무엇이 잘못되었는지 확신 할 수 없습니다. 정적 멤버가 초기화되지 않았기 때문에 분명했습니다. 하지만 왜? 예외는 main의 컨텍스트에서 throw되었습니다. 나는이 작은 프로젝트 전환으로 내 빌드 명령에 대한 무언가가 바뀌 었다고 생각한다. 솔루션을 가져 주셔서 감사합니다! –

+0

코드가 main 뒤에 실행 된 경우. 그렇다면 이것이 문제가 아닌 것 같습니다. 하지만 m_sNodeSet 이후에 생성되는 다른 전역 객체가이를 덮어 쓰는 중입니다. 위의 코드를 변경하면 merly가 주위를 움직 였고 이전의 잘못된 코드는 아직 덮어 쓰는 부분에 남아 있습니다. 이전처럼 보이지 않습니다. 모든 글로벌 변수에 대한 감사가 시작하기에 가장 좋은 장소라고 생각합니다. –

관련 문제