В вашем примере есть несколько проблем. Вот посмотрите на ваш код с некоторыми исправлениями:
#include <math.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
typedef struct node {
int tag;
struct node* next;
} node_t;
void createList(node_t**, int, int);
int main(int argc, char** argv)
{
int value = 10;
int totValues = (int)pow(2, value);
// `head` is an array of `node_t` pointers
// (aka. it is a `node_t**` not a `node_t*`)
node_t** head = (node_t**)calloc(totValues, sizeof(node_t*));
createList(head, 10, 20);
free(head);
return 0;
}
void createList(node_t **head, int tag, int index)
{
// You don't want `sizeof(sizeof(node_t))` because that is
// equivalent to sizeof(size_t) which is implementation defined,
// but usually equal to 4 or 8 depending on word size.
node_t* temp = (node_t*)calloc(1, sizeof(node_t));
temp->tag = tag;
temp->next = head[index];
head[index] = temp;
// You fill `temp` with information, point a spot in `head` to
// that pointer and then free the memory...
// That makes no sense. Don't do it!
free(temp);
}
Важно помнить, что free
не освобождает рекурсивно память для двойного указателя: вам нужно будет сделать это самостоятельно.
Вы должны вызвать free
на каждом узле в head
, а затем на самом head
:
createList(head, 10, 20);
free(head[20]); //Free the one node we created
free(head); // Free the array of nodes we created
и убедитесь, что вы закомментировали или удалили вызов free(temp);
в функции createList
.
Когда вы запустите valgrind на этом, утечек памяти больше не будет.
==6322== Memcheck, a memory error detector
==6322== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==6322== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==6322== Command: ./dynamic_memory
==6322==
==6322==
==6322== HEAP SUMMARY:
==6322== in use at exit: 0 bytes in 0 blocks
==6322== total heap usage: 2 allocs, 2 frees, 8,208 bytes allocated
==6322==
==6322== All heap blocks were freed -- no leaks are possible
==6322==
==6322== For counts of detected and suppressed errors, rerun with: -v
==6322== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
person
callyalater
schedule
13.10.2016
totValues
, я подозреваю, чтоcalloc(sizeof(totValues), sizeof(node_t));
должно бытьcalloc(totValues, sizeof(node_t));
- person Weather Vane   schedule 14.10.2016sizeof(sizeof(node_t))
? Удвоение оператораsizeof
- это не то, что вам нужно. - person callyalater   schedule 14.10.2016temp
, так как вы помещаете его в список с помощьюhead[index] = temp;
. - person Barmar   schedule 14.10.2016sizeof(sizeof(node_t))
неверно. Он выделяет достаточно места только для одногоint
, поэтому вы пишете за пределами границ, когда делаетеtemp->next = head[index];
- person Barmar   schedule 14.10.2016temp->next = head[index];
, вероятно, должно бытьtemp->next = &head[index];
. - person Barmar   schedule 14.10.2016node_t temp = (node_t) calloc(...)
должен быть указателем (т.е.node_t* temp = (node_t*)calloc(...)
). - person callyalater   schedule 14.10.2016head
был указателем на группу узлов, верно? Тогдаhead
, вероятно, должен бытьnode_t**
, не так ли? - person callyalater   schedule 14.10.2016temp
иhead
не являются узлами, это переменные, которые содержат адреса узлов. - person user253751   schedule 14.10.2016