2008-10-24 4 views
9

할당에 대해 꼬리를 구현하려고합니다. 나는 제대로 작동하지만 나는 임의의 시간에 자유에서 오류가 발생하는 것 같습니다.Malloc 오류 : 해제 된 개체의 체크섬이 잘못되었습니다.

나는 그것을 볼 수없고, 그 패턴 이외의 것을 추적하거나 일관성이 없다.

예를 들어, "tail -24 test.in"으로 프로그램을 호출하면 여러 줄에서 잘못된 줄 바꿈 오류가 발생합니다. 그러나 다른 파일과 심지어 줄 수를 다르게해서 인쇄해도 오류없이 다시 돌아올 것입니다.

문제를 추적하는 방법에 대한 아이디어는 몇 시간 동안 디버깅하려고 시도했지만 아무 소용이 없습니다.

라인 ** 숯불로 정의했다 malloc을있는 그대로 :

lines = (char**) malloc(nlines * sizeof(char *)); 

void insert_line(char *s, int len){ 

    printf("\t\tLine Number: %d Putting a %d line into slot: %d\n",processed,len,slot); 
    if(processed > numlines -1){//clean up 
    free(*(lines+slot)); 
    *(lines + slot) = NULL; 
    } 
    *(lines + slot) = (char *) malloc(len * sizeof(char)); 
    if(*(lines + slot) == NULL) exit(EXIT_FAILURE); 
    strcpy(*(lines+slot),s); 
    slot = ++processed % numlines; 
} 
+0

은 슬롯 0 또는 1 기반입니까? 슬롯이 nlines-1을 초과하지 마십시오. 맞습니까? – Dre

+0

오른쪽 모듈러스가 자동으로 0으로 돌아갑니다 – None

+0

어떤 컴파일러와 어떤 디버거를 사용하고 있습니까? 그에 따라 문제를 디버깅하는 데 도움이 될 수도 있습니다. –

답변

7

루틴이 할당 된 라인 버퍼를 초과하여 쓰고 있습니다.

인수 (예 : "len")로 전달 된 행의 크기에는 아마도 NUL 종결자가 포함되지 않습니다. 행 (즉, "s")을 복사하기 위해 malloc을 호출하면 문자열 터미네이터에 여분의 바이트를 할당해야합니다.

*(lines + slot) = (char *) malloc((len + 1) * sizeof(char)); 
+3

이 답변은 어떻게 받아 들여 졌습니까? 이 답변이 게시되기 전날 원래 게시자는 "null이 호출 기능에 의해 설명됩니다."라고 대답했습니다. –

0

이 NLINES를 수행하고 numlines가 같은 값이 여기에

는 잘못된 코드?

insert_line의 호출자는 두 번째 매개 변수에서 길이를 전달할 때 후미 NUL의 여유 공간을 허용합니까?

+0

예, nlines와 numlines은 같은 값입니다. 실제로 선의 선언은 어딘가에서 발생합니다. 널 (null)은 호출 함수에 의해 고려됩니다. – None

0

내가이 관련이 확실하지 않다 그러나이 두 줄이 나에게 의심스러운 : 후자는 NULL 인 경우

*(lines + slot) = (char *) malloc(len * sizeof(char)); 
    if((lines + slot) == NULL) exit(EXIT_FAILURE); 

가 먼저 lines[slot]에의 malloc의 반환을 할당 한 다음 (lines+slot)을 확인, 당신은했다 dereference NULL 포인터!

또한 [슬롯] (사용자의 * (lines + slot))이 null이 아닌 경우 malloc()의 결과를 할당 할 때 메모리가 누출됩니다.

나는 lineschar * lines []`이고 슬롯이 허용 된 경계 내에 있다고 가정합니다!

0

나는 두 줄에 대한 remo의 의혹에 동의하지만 remo가 시작된 탄젠트에 동의하지 않습니다. 이 버그를 찾아 내기 위해 우리는 신용을 공유해야합니다. 당신이 지속적으로 특정 입력 매개 변수를 사용하여 문제를 재현 할 수있는 경우

*(lines + slot) = some value 
if((lines + slot) == NULL) then die 
should be 
if(*(lines + slot) == NULL) then die 
+0

이 답변을 편집하는 동안 소스 코드를 편집했습니다. 이 경우 귀하의 버그는 아마도 아직 편집하지 않은 프로그램의 다른 부분에있을 것입니다 ... –

+0

나는 실제로 그것을 고쳤습니다 ... 그건 malloc에서 내 오류를 일으키는 것이 아닙니다. – None

3

, 당신은 다음과 같이 디버깅해야 문제를 유발하는 정확한 무료로

  • 먼저 디버그.
  • 그러면 free'd가 될 메모리가 malloc 될 때를 알 수 있습니다.
  • 다음으로 메모리가 malloc되어있는 곳으로 디버그하십시오.
  • 할당 된 메모리 블록을 메모리 뷰어에서 찾습니다. 블록의 시작과 끝을 모두 기록하십시오. 블록 바로 전과 직후에 가드 블록이라는 특별한 값이있을 것입니다.
  • 이제 메모리가 free'd 될 때까지 코드를 단계별로 실행하십시오. 어떤 점에서 코드가 실수로 가드 블록을 덮어 써야합니다. 그것은 불쾌한 진술입니다.

문제는 프로그램의 완전히 다른 부분에있을 수 있습니다. 이 오류를보고하는 것은 무료이지만, 가드 블록을 덮어 쓰는 코드는 어디든있을 수 있습니다.

+0

null이 포함되어 있습니다 당신이보고있는 코드는 내가 포인터를 조작하는 유일한 장소입니다. 엄청 이상해. – None

+0

일부 다른 코드는 할당 된 메모리 외부와 블록 주변의 가드 값에 쓰고있을 수 있습니다.그래서 malloc과 free 사이의 모든 코드를 단계별로 실행해야합니다. 어느 시점에서 일부 코드는 가드 값 중 하나를 덮어 씁니다. –

1

첫 번째 질문은 어떻게 len을 계산합니까? 그냥 strlen 또는 \ 0 터미네이터를위한 공간이 포함되어 있습니까? 나는 당신이 당신의 strcpy에서 당신의 할당을 오버 슛 (overshooting) 할 수 있다고 생각합니다. 나쁜 행동은 단어 경계에서 일어나는 경향이 있으며 무작위로 나타납니다. 또한 원본 문자열이 null로 종료되었는지 확인하십시오. 당신이 읽기 측면에서 실수를하고 그들을 끝내지 않았다면. 그럼 strcpy 무작위로 것들을 덮어 쓸 수 있습니다.

*(lines + slot) = (char *) malloc(len * sizeof(char)); 
    if(*(lines + slot) == NULL) exit(EXIT_FAILURE); 
    strcpy(*(lines+slot),s); 

아마 시도 : 일반적인 형태의 측면에서

lines[slot] = (char *) malloc((len + 1) * sizeof(char)); 
    if(lines[slot] == NULL) exit(EXIT_FAILURE); 
    if(strlen(s) <= len){ 
    strcpy(lines[slot],s); 
    } 
    else{ 
    /* do something else... */ 
    } 

, 나는 또한, 모든 것이 좀 더 읽을 수 있도록 몇 가지 문체 변경을 따라하기 쉽고 저항을 보시기 바랍니다 오류.

포인터 산술 유효하고 재미있다,하지만 난 당신이 같은 배열 형태로 사용하는 경우 사용자의 의도를 좀 더 명확하다고 생각 :

free(*(lines+slot)); 
*(lines + slot) = NULL; 

나는 또한 보시기 바랍니다

free(lines[slot]); 
lines[slot] = NULL; 

대신

을 너는 소수의 정체를 사용한다. 데이터 구조에서 쉽게 처리 할 수 ​​있으며 접근 자 및 변형 자에게 전달할 수 있습니다. 디버그 단지 비참 범위 지정 문제를 소개 할 수

static int numlines = 0; 
void insert_line(char *s, int len){ 
    int numlines = 5; 

:이 같은 일을하지 못하도록 조치가 일어나는 경우 훨씬 더 분명해진다.

관련 문제