2016-10-27 2 views
0

안녕하세요 저는 학교 프로젝트에 참여했으며 코드에 대한 도움이 필요합니다. exacly해시 테이블 valgrind 메모리 누수

기능은 테이블에 새로운 요소를 삽입 당신의 생각으로 무엇을 의미하는지 나는

이 오류 중 하나입니다 내가 얻을 무엇이 잘못되었는지를 해결하고 끔찍한 오류를 제거하기 위해 필요 Valgrind의를 사용

0x401CE9에 의해 strcpy (vg_replace_strmem.c : 458) 0x35C9B5에 의해 잘못된 쓰기 : HTab_insert (ial.c : 65) by 0x4019B5 : main (main.c : 82) 주소 0x5449785는 블록 뒤에 0 바이트입니다 0x4C28FA4에서 크기 5 alloc'd 의 : malloc (vg_replace_malloc.c : 296) by 0x401CC9 : HTab_insert (ial.c : 64) 0x4019B5에 의해 : 주 (main.c를 : 82)

HTab_listitem* HTab_insert(HTab_t* ptrht, Ttoken token) { 
    unsigned ind = hash_function(ptrht->htable_size,token); 
    HTab_listitem* item_ptr = NULL; 
    HTab_listitem* item = ptrht->list[ind]; 
    HTab_listitem* nextitem; 

    if(item == NULL) { 
     nextitem = malloc(sizeof(HTab_listitem)+sizeof(char)*(strlen(token.data)+1)); 

     if(nextitem == NULL) 
      /*allocation error*/ 
      return NULL; 
     else { 
      //printf("HERE\n"); 
      //printf("%s\n", token.data); 
      //memcpy(nextitem->token.data,token.data,strlen(token.data)+1); 
      int length = strlen(token.data); 
      nextitem->token.data = malloc(length * sizeof((char) +2)); 
      strcpy(nextitem->token.data,token.data); 
      nextitem->token.data[length] = '\0'; 
      nextitem->token.stav = token.stav; 
      //printf("HERE AFTER\n"); 
      nextitem->ptrnext = NULL; 

      item = ptrht->list[ind] = nextitem; 

      nextitem = NULL; 
      if(item == NULL) 
       return NULL; 
     } 
    } 
    else { 
     while(item != NULL) { 
      if(strcmp(item->token.data,token.data) == 0) { 
       //if found 
       item_ptr = item; 
       break; 
      } 
      else { 
       //next item 
       item_ptr = item; 
       item = item->ptrnext; 
      } 
     } 
     if(item_ptr != NULL && item != item_ptr) { 
      //not found insert next item 
      nextitem = malloc(sizeof(HTab_listitem*)+sizeof(char)*(strlen(token.data)+1)); 
      if(nextitem == NULL) 
       /*allocation error*/ 
       return NULL; 
      else { 
       //memcpy(nextitem->token.data,token.data,strlen(token.data)+1); 
       int length = strlen(token.data); 
       nextitem->token.data = malloc(length * sizeof((char) +2)); 
       strcpy(nextitem->token.data,token.data); 
       nextitem->token.data[length] = '\0'; 
       nextitem->token.stav = token.stav; 

       nextitem->ptrnext = NULL; 
       item = nextitem; 
       if(item == NULL) 
        return NULL; 
       item_ptr->ptrnext = item; 
      } 
     } 
    } 
    return item; 
} 
+1

[mcve]를 보여주십시오. –

+0

'token.data'를 복사하기 위해'strcpy'를 사용합니다. 'token.data'가 null로 끝났습니까? – GMichael

+1

이것은 올바르지 않습니다 (+2는 괄호 안에 있으면 안됩니다) :'malloc (length * sizeof ((char) +2))'. 'malloc (length +2)'를 의미합니까? (참고 : 'sizeof (char)'는 '1'이므로 생략 가능) –

답변

0

당신은 정의되지 않은 동작이 발생할 수있는 몇 가지 할당 오류가 있습니다. 다음은 충분해야 어디 nextitem-> token.data가 나중에 할당되기 때문에 나는 바닥

먼저 위쪽의 코드로 갈 것입니다, 당신은 많은 메모리

nextitem = malloc(sizeof(HTab_listitem)+sizeof(char)*(strlen(token.data)+1)); 

에 할당합니다.

int length = strlen(token.data); 
nextitem->token.data = malloc(sizeof(char) * (length + 1)); 
nextitem->token.data[length] = 0; 

두 번째 항목을 할당 다시 적당한 크기되지 않습니다 : token.data를 할당 할 때

nextitem = malloc(sizeof(HTab_listitem)); 

또한, 다음 사용합니다. 구조체의 크기 대신 포인터의 크기 (8 바이트)를 할당하고 token.data를 추가하는 것은 여전히 ​​유용하지 않습니다. previousely 완료로
nextitem = malloc(sizeof(HTab_listitem)); 

그런 다음 다시 token.data 할당 :해야

nextitem = malloc(sizeof(HTab_listitem*)+sizeof(char)*(strlen(token.data)+1)); 
//Error here (HTab_listitem*) 

.