문제

이것은 아주 이상한 나를 위해,그러나 나치 및 임의의 세그먼트 오류를 시작할 때 내 프로그램입니다.몇 번 그것은 작품,일부 시간이 다운받을 수 도 있습니다.디버거 개발-C++점을 줄일:stl_construct.h

/**
   * @if maint
   * Constructs an object in existing memory by invoking an allocated
   * object's constructor with an initializer.
   * @endif
   */
  template<typename _T1, typename _T2>
    inline void
    _Construct(_T1* __p, const _T2& __value)
    {
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 402. wrong new expression in [some_]allocator::construct
     -> ::new(static_cast<void*>(__p)) _T1(__value);
    }

내가 사용하여 STL 광범위한 방법에 의하여.나는 무엇을 해야 하을 감지하는 원산지의 세그멘테이션?이 있는 도구에서 도움을 받을 수 있습니까?무슨 이유로 이어질 수 있는 임의의 충돌은 이렇습니다.

편집:

내 프로그램을 계산 5,000 라인의 코드입니다.I don't know what 조각의 코드를 표시하기 위해서 어떤 도움을 받을 수가 없기에 대한 원산지의 문제,모든 나는 디버거에서 그것을 함께 할 수 있는 STL.

편집:

내가로 이동 Code::Blocks 이제 여기에 호출 스택:

#0 00464635 std::_Construct<std::pair<double const, int>, std::pair<double const, int> >(__p=0xb543e8, __value=@0x10) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_construct.h:81)
#1 00462306 std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_M_create_node(this=0x406fe50, __x=@0x10) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:367)
#2 00461DA7 std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_M_clone_node(this=0x406fe50, __x=0x0) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:379)
#3 004625C6 std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_M_copy(this=0x406fe50, __x=0x0, __p=0x406fe54) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:1029)
#4 00462A9D std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_Rb_tree(this=0x406fe50, __x=@0xb59a7c) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:559)
#5 0045A928 std::map<double, int, std::less<double>, std::allocator<std::pair<double const, int> > >::map(this=0x406fe50, __x=@0xb59a7c) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_map.h:166)
#6 0040B7E2 VehicleManager::get_vehicles_distances(this=0xb59a50) (C:/Program Files/CodeBlocks/MinGW/projects/AHS/VehicleManager.cpp:232)
#7 00407BDA Supervisor::IsMergeInstruction(id_vehicle=1) (C:/Program Files/CodeBlocks/MinGW/projects/AHS/Supervisor.cpp:77)
#8 00408430 CheckingInstructionsThread(arg=0x476100) (C:/Program Files/CodeBlocks/MinGW/projects/AHS/Supervisor.cpp:264)
#9 00413950 _glfwNewThread@4() (??:??)
#10 75A24911    KERNEL32!AcquireSRWLockExclusive() (C:\Windows\system32\kernel32.dll:??)
#11 00476100    std::__ioinit() (??:??)
#12 0406FFD4    ??() (??:??)
#13 76E5E4B6    ntdll!RtlInitializeNtUserPfn() (C:\Windows\system32\ntdll.dll:??)
#14 00476100    std::__ioinit() (??:??)
#15 70266582    ??() (??:??)
#16 00000000    ??() (??:??)

몇 가지 더 많은 정밀도:

1/그것은 멀티 스레드 응용 프로그램.2/방법:get_vehicles_distances();이 반환됩니다.3/한 지도는 없 initalised 에 의해 시간을 할 때 그것으로 불리 IsMergeInstruction();

편집:

분명히 줄을 일으키는 세그멘테이션은:

vehicles_distances_.erase(vehicles_distances_.begin(), vehicles_distances_.end());

는 vehicles_distances_ 맵입니다.이 줄은 방법의 일부:VehicleManager::MoveAllVehicles();

void VehicleManager::MoveAllVehicles() {

     vehicles_distances_.erase(vehicles_distances_.begin(), vehicles_distances_.end());

     vector<Vehicle>::iterator iter_end = VehicleManager::vehicles_.end();
     for(vector<Vehicle>::iterator iter = VehicleManager::vehicles_.begin();
     iter != iter_end; ++iter) {

          (*iter).MoveVehicle();

          vehicles_distances_[(*iter).get_vec_vehicle_position().y] = (*iter).get_id_vehicle();

     }

}

는 무엇입니까?

편집:

도 지도를 사용::clear();로 보충을 지도::삭제();하지만 같은 문제가 발생합니다!

편집:

내 생각에 나는 그것을 얻을...실을 만들기 위해 노력하고 사용 vehicles_distances_ 는 동안 그것은 지워..(?)

편집:

문제를 해결합니다!그래서 그것은에서 온 지도::삭제();으로 예상된다.나는 무시하여 문제를 만들 다른 지도 변수 한 쌍 <key, value> 었을 거꾸로 그렇게 업데이트 할 수 있습니다.(이후로는 키를 내가 필요로하는 거리,그리고 거리지 않은 독특한 이후 그것을 변경 할 때마다 하지만 id_vehicle 고유!).끝에 나만했는지도,거꾸로 <key, value> 다시 그대로 전달하는 원래의 지도할 수 있는 다시 선언에서 각 주기...

주셔서 감사합니다 모두가!

도움이 되었습니까?

해결책

첫째, 모든 것을 사랑하기 때문에, 사랑스럽고 사랑스럽고 Dev-C ++를 사용하지 마십시오. 나는 사람들이 그 쓰레기 조각에 어떻게 계속 달리기를 알고 있었으면 좋겠다. 유지되지 않았습니다 연령, 그리고 그것이 유지되었을 때에도 여전히 매우 기본적인 기능이 부족한 버그가 많은 쓰레기 조각이었습니다. 그것을 버리고 수많은 더 나은 무료 대안 중 하나를 찾으십시오.

이제 귀하의 질문에 : 귀하의 프로그램은 불법적 인 일을했기 때문에 무작위로 실현됩니다. 그렇게하지 마십시오. ;)

프로그램이 어딘가에 한계를 쓰지 않으면 어떤 일이 발생할 수 있습니다. 할당되지 않은 페이지에 도달 할 수 있으며,이 경우 segfault가 얻을 수 있습니다. 또는 프로세스에 할당 된 페이지의 미사용 데이터에 도달 할 수 있으며,이 경우 실제적인 영향을 미치지 않는 경우 (나중에 제대로 초기화되지 않는 한, 첫 번째, 불법, 쓰기를 덮어서 읽으려고 시도하지 않습니다. , 원래 (유효하지 않은) 값이 여전히 존재할 것으로 예상하거나 실제로 사용중인 데이터에 도달 할 수 있습니다.이 경우 프로그램이 해당 데이터를 읽으려고 할 때 나중에 오류가 발생합니다.

데이터를 읽을 때 거의 동일한 시나리오가 존재합니다. 운이 좋고 즉시 segfault를 얻거나 사용하지 않고 초기화되지 않은 메모리를 치고 쓰레기 데이터를 읽을 수 있습니다 (이 데이터가 사용될 때 나중에 오류가 발생할 가능성이 높습니다). 이미 사용 중입니다 (또한 쓰레기가 나옵니다).

그렇습니다. 이러한 오류는 찾기가 까다 롭습니다. 내가 줄 수있는 최선의 조언은 1) 기본 불일치가 유지 될 수 있도록 코드 전체에 뿌려지는 것입니다. 2) 프로그램을 진행하고 매 단계마다, 당신이 그 주소를 읽거나 쓰지 않는지 확인하십시오. t는 당신에게 속합니다.

MSVC에는 기본적으로 STL 코드에서 바운드 점검을 수행하는 보안 SCL 옵션이있어 이와 같은 오류를 발견하는 데 도움이 될 수 있습니다.

GCC는 비슷한 일을 할 수있는 옵션이 있다고 생각합니다 (그러나 기본적으로 활성화되지는 않습니다).

Segfaults는 불쾌합니다. 사람들이 이와 같은 오류에 몇 번이나 물린 후에는 한계에서 메모리에 액세스하는 것을 피하는 데 훨씬 더 많은 훈련을받는 경향이 있습니다. :)

다른 팁

당신은 시도 할 수 있습니다 Valgrind 문제를 찾는 데 도움이되는 방법으로. 당신이 질문에 넣은 줄을 감안할 때, 당신은 힙을 손상 시키거나 스택 문제가 있다고 생각해야합니다.

명백한 질문은 "_p는 무엇입니까"입니다. 디버거에서 Callstack을 볼 수 있어야합니다. _p를 기원으로 돌아갑니다. 올바른 크기를 확인하고 삭제되지 않았으며 실제로 존재하는지 확인하십시오.

쉽지 않은 경우, 항상 무작위 (의심되는) 코드를 작동하거나 돌아갈 때까지 알려진 작업 사본에 대한 차이가 항상 무작위 (의심되는) 코드를 댓글을 달아야합니다.

이것은 엄청나게 모호하기 때문에 대답하는 것은 거의 불가능합니다. 명백한 제안 중 하나는 모든 변수를 초기화하는지 확인하는 것입니다. 일부 컴파일러는 디버그에서 초기화되지 않은 물건을 제로화하고 예를 들어 릴리스에서는 그렇게하지 않으므로 무작위적이고 예상치 못한 결과를 초래합니다.

당신이 사용할 수있는 _CrtSetDbgFlag() 프로그램이 시작될 때 힙 디버깅 옵션을 활성화합니다. 또한보십시오 CRT 디버그 힙. 이것은 기억으로 나쁜 일을하는 곳을 추적하는 데 도움이 될 수 있습니다. MICROSOFT의 C 런타임에서 사용할 수 있으며 MINGW 컴파일러는 기본적으로 연결됩니다. 대신 GNU의 C 런타임을 사용하고 있다면이 경로를 갈 수 없습니다.

문제는 stl_construct.h보다 코드에있을 가능성이 훨씬 높습니다. 파일이 Dev-C ++의 STL 배포의 일부라고 가정합니다. stl_construct.h의 템플릿을 사용하여 인스턴스화 된 코드에서 분할 결함이 발생할 수 있지만 문제의 근본 원인은 다른 곳에있을 것입니다. 나는 충돌 시점에 스택 추적을 가져 와서 이것을 해결하려고 노력할 것이다. 스택 추적의 각 기능 (특히 새로 작성된 추적)에 대해 코드를 검사하고 다음 유형의 가능한 오류를 찾으십시오.

  • 비 초기 변수 (특히 배열 액세스에 사용되는 지수)
  • 메모리가 해제되거나 삭제 된 후 사용됩니다.
  • 배열은 배열의 범위 외부에 액세스합니다
  • NULL을 확인하지 않고 사용되는 메모리 할당 (NULL을 반환하지 않기 때문에 새로 사용하는 경우 문제가되지 않으면 예외가 발생합니다).

귀하의 설명 및 호출 스택,제안 프로그램은 충돌 초기화 하는 동안 정적 변수입니다.이것은 일반적인 문제의 C++:간단한 방법은 없을 제어하기 위해 초기화를 위해 정적 변수입니다.

예를 들어,당신의 프로그램도체 foo 에 따라 달라지는 개체 bar;하지만 그것이 될 수 있는 프로그램을 생성자를 호출 foo 하기 전에 구조 bar.나쁜 것,그리고 일으킬 수 있는 문제의 종류에 당신을 설명하고 있습니다.(가 CheckingInstructionsThread 정적 변수를 시작하는 스레드가?는 문제가 될 수 있습니다.)

이 문제를 해결하려면,당신이해야 할 수 있습니다 당신의 프로그램을 통해습니다.cpp 파일에 정적 변수를 포함하여(클래스 정적 및 globals),특히 그들의 일부는 클래스는 유형입니다.그것은 도움이되지 않을 수도 있습니다 수을 수정 당신의 생성자를 쓰는 몇 가지 추적하 stderr;사 fprintfcerr 는 경우 그렇게 할 수 있습니다.

편집:잘 모르시겠으면 여부도 함께 할 정역학,퍼팅하려고 다음과 같은 줄에서 시작 부분의 main():

 fprintf(stderr, "main() entered\n");

이지 않을 규칙을 정적으로 초기화 문제의 원인;하지 않는 경우에도 충돌main(), 에,당신은 여전히 있는 데이터 구조물을 설정이 잘못되었습니다.하지만,당신은 결코 얻을 fprintf,다음 는 정적 초기화가 원인일 수 있습니다.

코어 파일로 디버거를 실행 한 후 스택 추적이 무엇을 알려주나요? GDB를 정상적인 방법 GDB A.out로 실행하십시오

그런 다음 핵심 파일을 검사하십시오

핵심 A.out.core

그리고 스택을 살펴보십시오

BT

이것은 아마도 무효화 된 반복자와 관련이있을 것입니다. 컨테이너 위에 반복하거나 반복자를 컨테이너에 보관하고 동시에 요소를 제거/삽입하는 장소를 검색합니다.
그리고 다른 사람들이 지적했듯이 - 콜 스택을 사용하여 정확한 지점을 찾으십시오.

철저히 테스트 된 코드가 끝날 때 가장 먼저해야 할 일은 자신의 코드가 끝날 때까지 통화 스택을 올라가는 것입니다. 여기서이 문제가 발생하는 정보를 찾을 수 있습니다.

통화 스택에서 볼 수있는 가장 중요한 위치는 코드 (발신자)와 귀하가 호출 한 함수 (Callee)에 전달한 매개 변수입니다.

이 정보가 없으면 더 많은 도움을 줄 수 없습니다. ;-)

세분화 결함에 대한 자세한 내용 : http://en.wikipedia.org/wiki/segmentation_fault
(필수 읽기, 또한 "참조"및 "외부 링크"의 링크를 참조하십시오)

맵은 스레드 친화적이지 않습니다. 스레드 코드에서 맵 작업을 수행하는 경우 해당 맵에 대한 모든 액세스를 잠그고 보유 할 수있는 반복자가 무효화 될 수 있다는 것을 알아야합니다.

위험한 기능처럼 보입니다 :)

그래도 한 가지가 나를 때렸다. 할당 된 메모리는 어디로 갈까요? 직관적으로 나는 첫 번째 인수로 포인터에 대한 포인터를 갖고 싶다. 이와 같이:

template<typename _T1, typename _T2>
    inline void
    _Construct(_T1** __p, const _T2& __value)
    {

       ::new(static_cast<void*>(*__p)) _T1(__value);
    }

또는 포인터에 대한 참조 :

template<typename _T1, typename _T2>
    inline void
    _Construct(_T1*& __p, const _T2& __value)
    {

       ::new(static_cast<void*>(__p)) _T1(__value);
    }

디버거를 사용하면 통화 스택을 올릴 수 있습니다. 이렇게하면 자신의 코드에서 장소를 볼 수있어 Seg 결함이 발생합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top