나는 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 구조체를 볼 수 없습니다. 이 코드에 이와 같은 문제가 있습니까? 아니면 프로그램의 다른 부분을 봐야합니까?
첫 번째 생각 : Valgrind가 옳다. 프로그램이 현재 실행되고 있다고해서 오류가 없다는 의미는 아닙니다. – deviantfan
그리고 48 행을 보여주세요. –
'malloc (sizeof (* hashtable))'또는'calloc (3)'을 사용하십시오. – Antzi