2013-04-19 6 views
0

이 함수는 해시 테이블의 일부입니다. 검색 할 해시 목록과 키를 전달하고 있습니다. 나는 그것을 실행하려고하면 불행하게도, Valgrind의 나에게 오류초기화 Valgrind 오류

==1741== Conditional jump or move depends on uninitialised value(s) 
==1741== at 0x4018DE: HashSearch (Hash.c:81) 
==1741== by 0x400FA7: function (Nine13.c:181) 
==1741== by 0x4009D8: main (Nine13.c:54) 
==1741== 
==1743== Conditional jump or move depends on uninitialised value(s) 
==1743== at 0x4018DE: HashSearch (Hash.c:81) 
==1743== by 0x400FA7: function (Nine13.c:181) 
==1743== by 0x4009D8: main (Nine13.c:54) 
==1743== 

주고 계속

int HashSearch (Hash_list h, char* key) 
{ 
    struct ent *x = (struct ent *)malloc(10*sizeof(struct ent)); 
    for (x = h->table[hash(key, h->size)]; x!=0; x=x->next) { 
     if (strcmp(x->pos, key)==0) { 
      return x->num; 
     } 
    } 
    return -1; 
} 

(라인 81 "에 대한"로 시작하는 코드의 라인입니다).

struct ent과 전달 된 해시 목록을 모두 초기화 한 것 같습니다. 무엇이 잘못 되었나요?

+0

을 분리하십시오. 그래서'h-> table' 또는'x'가 문제를 일으키는 지 알 수 있습니다. 그런 다음 다시 작업하십시오. – John3136

+5

메모리를'x'에 할당하고'for' 루프에서'x'를 즉시 재 할당하면 메모리가 누수됩니다. –

+2

내 생각 엔 문제가 실제로 'HashSearch'외부에 있다는 것입니다. 'key'는 확실히 null로 끝났습니까? 'h-> table'에있는 모든 엔트리와 그 멤버 ('pos','next','num')는 초기화되어 있습니까? – jerry

답변

0

memset()을 사용하여 메모리를 지우거나 malloc() 대신 calloc() 기능을 사용하십시오.

+0

이것은 일반적으로 좋은 조언이지만 x는 즉시 재 할당되므로 여기서는 Valgrind 경고의 원인이 아닙니다 (메모리 누수 임에도 불구하고). 또한, 복잡한 데이터 타입을 가진 다른 형태의 초기화를 사용하는 것이 더 좋다. (memset과 calloc은 모두 모든 메모리 위치를 같은 값으로 설정한다. 복잡한 구조에서는 이해할 수 없다.) – jerry

1

우리 의견에 대한 귀하의 답변에서 귀하의 문제는 기능 밖에 있고 기능에서 사용 된 항목 중 하나가 제대로 초기화되지 않은 것 같습니다. 이 외부에서 코드의이 섹션에서 메모리 누수가 수행

struct ent *x = (struct ent *)malloc(10*sizeof(struct ent)); 
      ^^ 
    for (x = h->table[hash(key, h->size)]; x!=0; x=x->next) { 
     ^^^^^ 

당신이 x에 메모리를 할당 한 후 즉시 for 루프 x을 재 할당하는, 아마도 이것은 당신이해야 할 의미가 무엇인가 :

struct ent *x ; 
    for (x = h->table[hash(key, h->size)]; x!=0; x=x->next) { 
1

this other question에 따르면 h->table의 모든 항목이 초기화되지 않은 것이 문제였던 것으로 보입니다. tablecalloc 또는 memset을 사용하면 매우 높은 확률로 문제가 해결되지만 기술적으로는 이식 할 수 없습니다. 0은 널 포인터와 동일한 것으로 평가되지만, 비트 패턴은 모두 0이 될 수 있습니다. 또한 위의 다른 스레드와 내 주석에서 지적한 것처럼 복잡한 데이터 유형의 경우 다른 "빈"값을 원할 때가 많습니다.