2016-10-27 5 views
0

Привет Я работаю над школьным проектом и нуждаюсь в вашей помощи с кодом. Я использую Valgrind, чтобы выяснить, что это не так, и нужно, чтобы избавиться от ужасных ошибок, что exacly означает ваши мыслиHashtable valgrind memory leak

Функция вставляет новый элемент в таблицу

Это одна из ошибок, я получаю

Недопустимый записи размера 1 в 0x4C29B32: зЬгсру (vg_replace_strmem.c: 458) с помощью 0x401CE9: HTab_insert (ial.c: 65) от 0x4019B5: основная (main.c: 82) Адрес 0x5449785 составляет 0 байт после блока от размера 5 alloc'd по адресу 0x4C28FA4: malloc (vg_replace_malloc.c: 296) от 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

Вы используете 'strcpy' для копирования' token.data'. Вы уверены, что 'token.data' имеет значение null? – GMichael

+1

Это неверно (+2 не должно быть в скобках): 'malloc (length * sizeof ((char) +2))'. Вы имеете в виду 'malloc (length +2)'? (Боковое примечание: 'sizeof (char)' is '1' и, следовательно, может быть опущен) –

ответ

0

У вас есть несколько ошибок распределения, которые могут привести к непредсказуемому поведению. Я пойду в код, сверху донизу

Во-первых, вы выделить много памяти

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

Где следующее должно быть достаточно, так как nextitem-> token.data выделяется впоследствии.

nextitem = malloc(sizeof(HTab_listitem)); 

Кроме того, при выделении token.data, используйте следующее:

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

Ваше второе распределение элемент снова не правильный размер. Вы выделяете sizeof указателя (8 байтов) вместо размера вашей структуры и добавление token.data все еще не полезно.

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

Это должно быть:

nextitem = malloc(sizeof(HTab_listitem)); 

Затем снова выделить token.data, как это сделано previousely.