2014-11-17 2 views
0

나는 stdin에서 파일을 가져 와서 인코딩하고 stdout으로 인쇄해야하는 프로그램을 가지고 있습니다 (기본 단계에서). .프로그램이 완벽하게 작동 할 때 고함을 지르는 Valgrind

int lzw_encode() 
{ 
    table* hashtable; 
    int counter=0; 
    hashtable = initialize(); //line 196 
    int code = -1; 
    char k; 
    if ((k=getc(stdin))==EOF) 
    { 
     return 0; 
    } 
    code = k; 
    while ((k=getc(stdin))!=EOF) 
    { 
     if (HashSearch(hashtable, code, k)!=-1) 
     { 
      code=HashSearch(hashtable, code, k); 
     } 
     else 
     { 
      putBits(12, code); 

      if (hash(code, k, hashtable->size)>4340) 
      { 
       counter=1; 
      } 
      if (counter==0) 
      { 
       hashtable = insertObject(hashtable, code, k); //line 228 
      } 

      code = HashSearch(hashtable, -1, k); 

     } 
    } 
    if (code != 0) 
    { 
     printf ("%d\n", code); 
    } 
    /*if (!fp) 
    { 
     printf("????\n"); 
    }*/ 

    return 0; 
} 

: 여기

==6508== Invalid read of size 4 
==6508== at 0x4009EC: insertObject (lzw.c:106) 
==6508== by 0x400B72: lzw_encode (lzw.c:228) 
==6508== by 0x40091D: main (lzw.c:48) 
==6508== Address 0x5203044 is 0 bytes after a block of size 65,540 alloc'd 
==6508== at 0x4C2845D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==6508== by 0x400D51: initialize (lzw.c:305) 
==6508== by 0x400AB3: lzw_encode (lzw.c:196) 
==6508== by 0x40091D: main (lzw.c:48) 
==6508== 

코드의 관련 단편이다 : 그것은 아무리 내가 읽어 표준 입력의 유형, 잘 작동하지 않을 것 같다 그러나, Valgrind의 날을 말하고하는 것은 문제가있는 것입니다 은 insertObject :

table *insertObject (table *h, int pref, char ch) 
{ 
    struct node x; 
    int i; 
    if (ch < 0) 
    { 
     ch=4096-ch; 
    } 
    x.chr=ch; 
    x.pref=pref; 
    i = hash(pref, ch, h->size); 
    while (h->hash[i].pref!=0) 
    { 
     i++; 
    } 
    if (i>4340) 
    { 
     return h; 
    } 
    h->hash[i]=x; //line 106 
    return h; 
} 

초기화 :

table *initialize() 
{ 
    table *hashtable = malloc(sizeof(table)); //Line 305 
    //hashtable->hash = malloc (sizeof(struct node) * 4096); 
    memset(hashtable, 0, sizeof(*hashtable)); 
    hashtable->size=4096; 
    //hashtable->hash=malloc(sizeof(table)); 
    for (int i=0; i<4096; i++) 
    { 
     hashtable->hash[i].pref=-1; 
     hashtable->hash[i].before=-1; 
     hashtable->hash[i].after=-1; 
     hashtable->hash[i].chr=0; 
    } 
    for (int i=0; i<256; i++) 
    { 
     hashtable->hash[i].chr=i+128; 
    } 
    //printf("Initialized\n"); 
    return hashtable; 
} 

valgrind에 언급 된 행에 레이블을 붙였습니다.

편집 :

typedef struct hash_t table; 

struct node { 
    int pref; 
    int before; 
    int after; 
    char chr; 
}; 

struct hash_t { 
    int size; 
    struct node hash[4096]; 
}; 

EDIT2 : 내가 그것을 해결 한 것 같다 4096 이상 진행하지 있는지 확인 만들기

다음은 데이터 구조입니다. 이 사이트에 다른 질문을 바탕으로

==20137== Syscall param write(buf) points to uninitialised byte(s) 
==20137== at 0x4F198B0: __write_nocancel (in /usr/lib64/libc-2.17.so) 
==20137== by 0x4EA8E32: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libc-2.17.so) 
==20137== by 0x4EAA29B: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libc-2.17.so) 
==20137== by 0x4EABDE6: _IO_flush_all_lockp (in /usr/lib64/libc-2.17.so) 
==20137== by 0x4EABF39: _IO_cleanup (in /usr/lib64/libc-2.17.so) 
==20137== by 0x4E6AE0A: __run_exit_handlers (in /usr/lib64/libc-2.17.so) 
==20137== by 0x4E6AEA4: exit (in /usr/lib64/libc-2.17.so) 
==20137== by 0x4E53AFB: (below main) (in /usr/lib64/libc-2.17.so) 
==20137== Address 0x4023002 is not stack'd, malloc'd or (recently) free'd 

는,이 구조체가 초기화되지 않을 때 발생하는 것 같습니다 그러나, 나는이와 전에 본 적이 Valgrind의 오류를 발견했다. 그러나, 나는 unititialized 구조체를 볼 수 없습니다. 이 코드에 이와 같은 문제가 있습니까? 아니면 프로그램의 다른 부분을 봐야합니까?

+8

첫 번째 생각 : Valgrind가 옳다. 프로그램이 현재 실행되고 있다고해서 오류가 없다는 의미는 아닙니다. – deviantfan

+0

그리고 48 행을 보여주세요. –

+0

'malloc (sizeof (* hashtable))'또는'calloc (3)'을 사용하십시오. – Antzi

답변

2

의 106 번째 줄에 주소 hash[i]에서 읽으려고합니다. hash의 크기는 4096이지만 위의 네 줄이 i > 4340 인 경우에만 확인했습니다. 프로그램을 실행하는 동안 i 값이 4096에서 4340 사이 일 수 있습니다.

첫 번째 Valgrind 출력 블록은 주소 hash + i * sizeof(struct node)에서 요청 된 4 바이트를 읽을 수 없다는 것을 알려줍니다.

두 번째 블록은 읽으려고하는 주소가 할당 된 크기 65,540의 배열 끝을 지나치고 있음을 나타냅니다. 실제로 h 변수가 insertObject으로 전달되었습니다.

일반적인 Valgrind 오류 보고서에 대한 설명은 http://valgrind.org/gallery/linux_mag.html을 참조하십시오.