I am using valgrind to fix memory leaks in my C program, and there is one particular function that seems to be the source of most of the valgrind errors
typedef struct Array {
int capacity;
int size;
void **items;
} Array;
Array *createArray(int capacity) {
Array *array = malloc(sizeof(Array));
array->capacity = capacity;
array->size = 0;
void **items = malloc(sizeof(void *) * array->capacity * sizeof *items);
if(items == NULL) {
exit(1);
}
array->items = items;
return array;
}
The first line of the createArray
function is throwing the following error in Valgrind
1,296 (16 direct, 1,280 indirect) bytes in 1 blocks are definitely lost in loss record 34 of 42
Am I not using malloc in the right way to allocate memory?
As discussed above in the comments, it is unclear why you allocate items
with:
void **items = malloc(sizeof(void *) * array->capacity * sizeof *items);
(which essentially allocates 8x (an additional multiple of sizeof "a pointer"
) number of pointers than would be required)
Instead, if you are allocating array->capacity
pointers for items
, then use:
void **items = malloc(array->capacity * sizeof *items);
Your valgrind
error does not look like an error, but the result of not calling free
on the memory you allocate, leaving valgrind
to report the bytes lost (still reachable on exit). You can easily free the memory on exit with a simple destroyArray
function similar to:
void destroyArray (Array *array) {
for (int i = 0; i < array->size; i++)
free (array->items[i]);
free (array->items);
free (array);
}
Putting it altogether you could do something like:
#include <stdio.h>
#include <stdlib.h>
typedef struct Array {
int capacity;
int size;
void **items;
} Array;
Array *createArray (int capacity) {
Array *array = malloc (sizeof *array);
array->capacity = capacity;
array->size = 0;
void **items = malloc(array->capacity * sizeof *items);
if(items == NULL) {
exit(1);
}
array->items = items;
return array;
}
void destroyArray (Array *array) {
for (int i = 0; i < array->size; i++)
free (array->items[i]);
free (array->items);
free (array);
}
int main (void) {
Array *a = createArray (10);
printf ("%d capacity\n", a->capacity);
destroyArray (a);
return 0;
}
( note: you should also validate Array *array = malloc (sizeof *array);
succeeded and (array != NULL)
before attempting to use array
)
Memory Use/Error Check
$ valgrind ./bin/allocstruct
==5777== Memcheck, a memory error detector
==5777== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==5777== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==5777== Command: ./bin/allocstruct
==5777==
10 capacity
==5777==
==5777== HEAP SUMMARY:
==5777== in use at exit: 0 bytes in 0 blocks
==5777== total heap usage: 2 allocs, 2 frees, 96 bytes allocated
==5777==
==5777== All heap blocks were freed -- no leaks are possible
==5777==
==5777== For counts of detected and suppressed errors, rerun with: -v
==5777== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Look things over and let me know if this is what you were concerned with.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.