2012-04-11 1 views
0

메모리 할당량이 많아서이 동일한 프로그램으로 문제가 발생했습니다. 나는 대부분의 문제를 없애고 있지만 여전히 한 가지 특별한 문제에 문제가 있습니다. 이클립스 내 프로그램을 실행하면 그것을 잘 컴파일하지만 Valgrind의 그것을 실행했을 때 그것이 나에게 알려줍니다이 메시지메모리 문제로 인해 C 프로그램이 충돌하지만 디버깅 중에 충돌이 발생하지 않습니까?

*** glibc detected *** /home/user/workspace/TTPrueba/Debug/TTPrueba: free(): invalid pointer: 0xb6bc0588 *** 

와 충돌이

==31580== Process terminating with default action of signal 11 (SIGSEGV) 
==31580== Access not within mapped region at address 0x0 
==31580== at 0x804BEA3: termino (Menu.c:899) 
==31580== by 0x804BE05: computar_transformadas (Menu.c:840) 

그래서 문제는 무료로 노력하고 있다는 것입니다 잘못된 메모리 주소이지만 디버그 모드에서 한 단계 씩 나아가고 프로그램은 결코 충돌하지 않습니다 !! :(

은?이 꽤 이상한 행동 그런 일이 디버깅하는 동안 만 실행되지 동안 작동 와서 어떻게? 일어날 수있는 이유를 생각 어떤. 도움을

for(phi=0;phi<360;phi++){ 

     for(j=0;j<par.param1[phi][0];j++){ 


       for(o=0;o<(par.prueba[phi][j][1]-par.prueba[phi][j][0]);o++){//AQUI 849 

       free(par.pixels[phi][j][o]);//HERE IS LINE 899 WHERE IT ALWAYS CRASHES 

       if(o==(par.prueba[phi][j][1]-par.prueba[phi][j][0]-1)) 
        free(par.pixels[phi][j]); 

       } 


      free(par.prueba[phi][j]); 

     } 

감사합니다! 가능성

+5

아. 사랑스럽고 거의 * 아주 희귀 한 것은 아닙니다. [Heisenbug] (http://en.wikipedia.org/wiki/Heisenbug)는 자연 서식지입니다. 깃털의 아름다운 위장 무늬를 보시나요? 그게 뭐야? 너는 그것을 볼 수 없는가? 네, 그렇습니다. 그것이 그곳에 있음을 당신이 아는 방식입니다. – dmckee

+2

디버거에서 메모리가 0 일 수도 있습니다. 프로그램에서이 경우가 아닐 수도 있습니다. malloc을 callocs로 변경하십시오. – Mikhail

+2

"디버그 모드에서 단계별로 진행하고 프로그램이 절대로 충돌하지 않습니다 !!!!"- 디버깅의 세계에 오신 것을 환영합니다! –

답변

0

하나 이유 - 디버거가 사물의 메모리 레이아웃을 바꿀 수 있으므로 메모리가 손상되면 "비공개"장소에있게됩니다.

또는 디버거가 할당 된 메모리를 0으로 만들 수 있습니다. 생산에서 일어날 수 없다. 유엔.

+1

또는 중단 점에서 중지하기 위해 디버거를 사용하는 암시 적 동기화는 스레드의 타이밍 상호 작용을 변경합니다 ... (다중 스레드 인 경우) –

+0

아니 멀티 스레드이므로 문제가되지 않습니다. 일부 unitialized 값이 문제라고 생각합니다. – Atirag

0

놀라운 것은 아닙니다. 예를 들어, par.pixels [phi] [j] [o]가 초기화되지 않은 경우. 그것은 무엇이든 포함 할 수 있습니다. 디버거 환경에서 다른 메모리 레이아웃을가집니다. par.pixels [phi] [j] [o]가 0이되어 free가 중단되지 않습니다. 내가 볼

+0

나는 이것을 mallocs 대신 calloc을 사용하여 고치려고했지만 쓸모가 없다. ... – Atirag

+0

calloc을 사용하는 것 이외에 (포인터가 처음에 NULL로 설정되도록하고, 실수로 잘못 참조를 취소하려는 시도) 포인터를 설정하는 것이 좋다. 그들이 가리키는 메모리를 해제 한 후 NULL을 반환합니다 (같은 이유로). 또는 때로는 디버깅 할 때 오류 메시지/디버그 인쇄에서 눈에 띄는 "독"값 (예 : 0xdeadbeefdeadbeef)이 있습니다. –

+0

어떻게하면됩니까? 예를 들어 내가 무료 일 경우 (par.pixelsφ [j] [o]); 나 후에 뭔가해야합니까? – Atirag

0

하나의 문제는 당신이 무료 par.pixels[phi][j][o]o 0에서 루핑, 그리고이 다음 액세스par.pixels[phi][j][0]가 단지 free되기를되어있는 것입니다!

또한 par.pixels[phi][j]을 무료로 사용할 수 있지만 계속해서 루프 par.pixels[phi][j]에 액세스하고 더 이상 유효하지 않은 포인터를 해제하십시오.

+0

par.pixels [j] [0]에 액세스 한 후 par.pixels [j] [0]에 액세스하지 않습니다. par.prueba [ph] [j] [0]에 액세스합니다. – Atirag

+0

또한 par.pixels [φ]을 무료로 사용할 때 마지막 루프인지 확인하여 다음 루프에서 빠져 나와 메모리를 확보하지 못하도록합니다. – Atirag