2014-10-22 1 views
0

I 코드를 가지고 수행되어야하는 코드와 같은, 느낌표 부분에 선행하는 라인의 첫 번째 정수를 얻을 무엇임의 문자

else if ((strtolnum=(strtol(&oldline[b+1],NULL,10)))>0) 
     { 
      char* excl = malloc(3*sizeof(char)); 
      excl[0]=oldline[b]; 
      excl[1]=oldline[b+1]; 
      for (int j = 0; j<strtolnum; j++) 
      { 
       llist=llist->nextcmd; 
      } 
      struct token *p1; 
      struct token *save1 = llist->cmmd; 
      char *arra1 = malloc(sizeof(char)); 
      memset(arra1, '\0', 1); 
      for (p1 = llist->cmmd; p1 != NULL; p1 = p1->next) { 
       arra = realloc(arra1, strlen(arra1)+strlen(p1->text)+2); 
       strcat(arra, p1->text); 
       if (p1->next!=NULL) 
       { 
        strcat(arra1, " "); 
       }// printing token and type 
      } 
      printf("%s excl\n", excl); //Line 137 
      oldline=strreplace(oldline,excl,arra1); //Line 138 
      llist->cmmd=save1; 
      for (int j = 0; j<(f-strtolnum); j++) 
      { 
       llist=llist->nextcmd; 
      } 
      *status=1; 
      size_t a = sizeof(excl); 
      memset(excl,'\0', a); 
     } 

! 3, 그리고 excl에 넣습니다 (그리고 나서 완벽하게 잘 작동하는 다른 것들을하십시오).

그러나 반복문을 두 번 이상 실행하면 excl에 printf를 시도 할 때 "! 3e"로 표시 될 때와 같이 끝에 excl이 종종 임의의 문자를가집니다. Valgrind는 다음과 같은 오류를 표시합니다.

==24878== Conditional jump or move depends on uninitialised value(s) 
==24878== at 0x4E7AB5B: vfprintf (in /usr/lib64/libc-2.17.so) 
==24878== by 0x4E83CD8: printf (in /usr/lib64/libc-2.17.so) 
==24878== by 0x40130F: hExpand (Lex1.c:137) 
==24878== by 0x400B6B: main (mainLex.c:27) 
==24878== 
==24878== Conditional jump or move depends on uninitialised value(s) 
==24878== at 0x4C2B308: strlen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==24878== by 0x4020D7: strreplace (Lex1.c:562) 
==24878== by 0x40132C: hExpand (Lex1.c:138) 

명백히 excl은 루프가 한 번 통과 한 후에 하나씩 초기화됩니다. 뭐가 잘못 되었 니?

자세한 내용은 cmmd가 토큰 유형의 데이터 구조이고 llist가 토큰을 포함하는 전역 정적 데이터 구조입니다.

+0

'excl' 문자열을 null로 끝내지 않았습니다. 'malloc()'은 임의의 쓰레기를 반환합니다. –

+0

다음 줄 : size_t a = sizeof (excl); memset (excl, '\ 0', a); excl 포인터의 4 바이트를 항상 0x00으로 설정합니다. 이로 인해 메모리 누수가 발생하고 excl은 메모리의 첫 번째 바이트를 가리 킵니다. 실제로 할당 된 메모리 (모든 경우에 3 바이트가됩니다)의 값을 지우려고하면 아마도 memset (excl, '\ 0', 3); – user3629249

+0

@ user3629249 : 포인터 자체를 0으로 설정하지 않습니다. 포인터가 가리키는 메모리를 0으로 설정합니다. 포인터를 0으로 만들려면'memset (& excl, '\ 0', a);'를 호출해야합니다. –

답변

2

excl 문자열을 null로 끝내지 않았습니다. malloc()은 임의의 쓰레기를 반환합니다. 당신은 추가에 대해 생각 : 당신이 중 하나를 4 또는 8 (32 비트 또는 64 비트) a에 할당 한 다음 쓰기

size_t a = sizeof(excl); 
memset(excl,'\0', a); 

:

excl[2] = '\0'; 

또한 탈출구 경계에 짓밟 그 많은 바이트 이상,하지만 당신은 excl 3 바이트를 할당했습니다.