alloc and free of 2d array - c

I made 2d array(matrix) + alloc and free functions to manage memory but it isnt working well, valgrind prints many errors and information that memory was lost.
Alloc: parametr s means size of matrix
int** alloc(int s)
{
int** matrix;
int i;
matrix = (int**)malloc(s * sizeof(int*));
for (i = 0; i < s; i++)
{
matrix[i] = calloc(s, sizeof(int));
}
return matrix;
}
Free
void matrix_free(int*** matrix, int s)
{
int i;
for(i = 0; i < s; i++)
{
free(*((matrix)+i));
}
free(matrix);
}
Valgrind:
Many errors like this:
Invalid read of size 8
==3767== at 0x4FAA8D4: buffer_free (in /lib/x86_64-linux-gnu/libc-2.24.so)
==3767== by 0x4FAA942: __libc_freeres (in /lib/x86_64-linux-gnu/libc-2.24.so)
==3767== by 0x4A276EC: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so)
==3767== by 0x4E73292: __run_exit_handlers (exit.c:98)
==3767== by 0x4E73339: exit (exit.c:105)
==3767== by 0x4E593F7: (below main) (libc-start.c:325)
==3767== Address 0x52000e8 is 168 bytes inside a block of size 552 free'd
==3767== at 0x4C2DD6B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3767== by 0x108BBB: matrix_free (m1.c:68)
==3767== by 0x108B69: main (m1.c:58)
==3767== Block was alloc'd at
==3767== at 0x4C2CB3F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3767== by 0x4EA7F2C: __fopen_internal (iofopen.c:69)
==3767== by 0x108919: main (m1.c:16)
==3767==
==3767==
==3767== HEAP SUMMARY:
==3767== in use at exit: 36 bytes in 3 blocks
==3767== total heap usage: 7 allocs, 6 frees, 5,732 bytes allocated
==3767==
==3767== LEAK SUMMARY:
==3767== definitely lost: 36 bytes in 3 blocks
==3767== indirectly lost: 0 bytes in 0 blocks
==3767== possibly lost: 0 bytes in 0 blocks
==3767== still reachable: 0 bytes in 0 blocks
==3767== suppressed: 0 bytes in 0 blocks

The free function in this case doesn't take a pointer that points to the allocated memory, but a pointer to that pointer.
To free the memory you need to first obtain that pointer.
void matrix_free(int*** matrix, int s)
{
int** m = *matrix;
int i;
for(i = 0; i < s; i++)
{
free( m[i] );
}
free( m );
*matrix = NULL;
}
This variant also enables you to set the argument to NULL:
matrix_free( &matrix , s );
assert( matrix == NULL );

Related

Invalid read of size 8. Trying to make a 2D array

Trying to make a 2D array and am getting this error from valgrind
==226== HEAP SUMMARY:
==226== in use at exit: 0 bytes in 0 blocks
==226== total heap usage: 38 allocs, 38 frees, 9,793 bytes allocated
==226==
==226== All heap blocks were freed -- no leaks are possible
==226==
==226== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==226==
==226== 1 errors in context 1 of 2:
==226== Invalid read of size 8
==226== at 0x108BB7: freeBoard (Battleships.c:55)
==226== by 0x108B81: createBoard (Battleships.c:47)
==226== by 0x108AD6: main (Battleships.c:30)
==226== Address 0x522ff60 is 0 bytes after a block of size 32 alloc'd
==226== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==226== by 0x108B29: createBoard (Battleships.c:40)
==226== by 0x108AD6: main (Battleships.c:30)
==226==
==226==
==226== 1 errors in context 2 of 2:
==226== Invalid write of size 8
==226== at 0x108B5D: createBoard (Battleships.c:44)
==226== by 0x108AD6: main (Battleships.c:30)
==226== Address 0x522ff60 is 0 bytes after a block of size 32 alloc'd
==226== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==226== by 0x108B29: createBoard (Battleships.c:40)
==226== by 0x108AD6: main (Battleships.c:30)
==226==
==226== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
This is the code that is allocating/freeing
void createBoard(int* widthPtr, int* heightPtr) /* Creates the 2D Board Array. */
{
char** board;
int i;
board = (char**)malloc((*heightPtr) * sizeof(char*));
for (i = 0; i < *widthPtr; i++)
{
board[i] = (char*)malloc((*widthPtr) * sizeof(char));
}
freeBoard(board, widthPtr);
}
void freeBoard(char** board, int* widthPtr)
{
int i;
for (i = 0; i < *widthPtr; i++)
{
free(board[i]);
}
free(board);
}
I'm trying to make a 2D array of a specified width/height which are integers. In each section of the array a char will be stored.
Any help would be great, thanks.
for (i = 0; i < *widthPtr; i++)
{
board[i] = (char*)malloc((*widthPtr) * sizeof(char));
}
should be
for (i = 0; i < *heightPtr; i++)
{
board[i] = (char*)malloc((*widthPtr) * sizeof(char));
}
Otherwise you iterate NCOLUMNS times (you want to iterate through the NROWS dimension)
Same for freeBoard()
Also, notice that in this line
board[i] = (char*)malloc((*widthPtr) * sizeof(char));
you prefer
board[i] = malloc(*widthPtr);
because:
1) There is no need to cast malloc and friends
2) sizeof(char) is guaranteed to be 1

Valgrind definitely lost block of memory

I am trying to figure out what is wrong with my valgrind debugging. I am starting to learn valgrind and there are some things I do not know how to solve
==12902== HEAP SUMMARY:
==12902== in use at exit: 40 bytes in 4 blocks
==12902== total heap usage: 21 allocs, 17 frees, 2,400,792 bytes allocated
==12902==
==12902== Searching for pointers to 4 not-freed blocks
==12902== Checked 77,768 bytes
==12902==
==12902== 40 (16 direct, 24 indirect) bytes in 2 blocks are definitely lost in loss record 2 of 2
==12902== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12902== by 0x400EAB: elequeue_ini (elequeue_point.c:15)
==12902== by 0x400F90: elequeue_copy (elequeue_point.c:67)
==12902== by 0x4012EC: queue_insert (queue.c:105)
==12902== by 0x400C24: main (p3_e1.c:85)
==12902==
==12902== LEAK SUMMARY:
==12902== definitely lost: 16 bytes in 2 blocks
==12902== indirectly lost: 24 bytes in 2 blocks
==12902== possibly lost: 0 bytes in 0 blocks
==12902== still reachable: 0 bytes in 0 blocks
==12902== suppressed: 0 bytes in 0 blocks
==12902==
==12902== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==12902== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Elequeue makes reference to the elements of a queue ADT. The codes involved are:
struct _EleQueue{
Point *info;
};
EleQueue* elequeue_copy(const EleQueue * src){
EleQueue *copied_ele;
if(src==NULL){
return NULL;
}
copied_ele=elequeue_ini();
if(copied_ele==NULL){
return NULL;
}
copied_ele->info=point_copy(src->info);
return copied_ele;
}
EleQueue* elequeue_ini(){
EleQueue *e;
e=(EleQueue*)malloc(sizeof(EleQueue));
if (e==NULL){
return NULL;
}
e->info=NULL;
return e;
}
Queue* queue_insert(Queue *q, const EleQueue* pElem){
EleQueue *auxElem;
if(!q || !pElem || queue_isFull(q) == TRUE){
return NULL;
}
auxElem=elequeue_copy(pElem);
if(auxElem == NULL){
return NULL;
}
*(q->end) = auxElem;
if(q->end == &(q->item[MAXQUEUE-1])){
q->end = &(q->item[0]);
} else {
q -> end++;
}
return q;
}

Free LINKED LIST in C

Here is the structures.
struct webPage{
struct wordOccurance *rootWord;
char URL[..];
};
struct wordOccurance{
struct wordOccurance *nextWord;
char word[...];
};
//Crawl and populate all words...
struct webPage *hopPage(url...){
[scan all words in the web page]
insertBackOfList(malloc(sizeof(struct wordOccurance)).. word)
}
//Now free..
void destroyPage(struct webPage *target){
while(target != NULL){
struct webPage *temp = target->next;
destroyWords(target->rootWord);
free(target);
target = temp;
}
}
void destroyWords(struct wordOccurance *target){
while(target != NULL){
struct wordOccurance *temp = target->nextWord;
free(temp);
target = temp;
}
}
==20169== Invalid read of size 4
==20169== at 0x8048DD5: destroyWords (index.c:109)
==20169== by 0x80492E2: destroyPage (crawler.c:166)
==20169== by 0x8049797: main (webSearch.c:91)
==20169== Address 0x41d5298 is 0 bytes inside a block of size 1,008 free'd
==20169== at 0x4024B3A: free (vg_replace_malloc.c:366)
==20169== by 0x8048DE4: destroyWords (index.c:110)
==20169== by 0x80492E2: destroyPage (crawler.c:166)
==20169== by 0x8049797: main (webSearch.c:91)
==20169==
==20169== Conditional jump or move depends on uninitialised value(s)
==20169== at 0x8049781: main (webSearch.c:90)
==20169==
==20169==
==20169== HEAP SUMMARY:
==20169== in use at exit: 52,432 bytes in 52 blocks
==20169== total heap usage: 95 allocs, 43 frees, 82,392 bytes allocated
==20169==
==20169== 1,008 bytes in 1 blocks are definitely lost in loss record 2 of 8
==20169== at 0x4024F20: malloc (vg_replace_malloc.c:236)
==20169== by 0x8048A7F: indexPage (index.c:26)
==20169== by 0x8048F1D: hopURL (crawler.c:46)
==20169== by 0x8049570: main (webSearch.c:52)
==20169==
==20169== 1,008 bytes in 1 blocks are definitely lost in loss record 3 of 8
==20169== at 0x4024F20: malloc (vg_replace_malloc.c:236)
==20169== by 0x8048A7F: indexPage (index.c:26)
==20169== by 0x80490E7: insertBack (crawler.c:108)
==20169== by 0x8048FAB: hopURL (crawler.c:66)
==20169== by 0x8049570: main (webSearch.c:52)
==20169==
==20169== 50,416 (1,012 direct, 49,404 indirect) bytes in 1 blocks are definitely lost in loss record 8 of 8
==20169== at 0x4024F20: malloc (vg_replace_malloc.c:236)
==20169== by 0x8048E8F: hopURL (crawler.c:28)
==20169== by 0x8049570: main (webSearch.c:52)
==20169==
==20169== LEAK SUMMARY:
==20169== definitely lost: 3,028 bytes in 3 blocks
==20169== indirectly lost: 49,404 bytes in 49 blocks
==20169== possibly lost: 0 bytes in 0 blocks
==20169== still reachable: 0 bytes in 0 blocks
==20169== suppressed: 0 bytes in 0 blocks
==20169==
==20169== For counts of detected and suppressed errors, rerun with: -v
==20169== Use --track-origins=yes to see where uninitialised values come from
==20169== ERROR SUMMARY: 356 errors from 13 contexts (suppressed: 14 from 7)
From both destroyPage() and destroyWords():
free(temp);
target = temp;
You are setting a variable to a pointer which you just freed. This is never correct.
The correct logical sequence to free a singly linked list is generally:
while (ptr) {
oldPtr = ptr;
ptr = ptr->next;
free(oldPtr);
}
Why are you setting target = temp after you just freed temp?
Remove that line and simply do:
struct wordOccurrence *temp;
while (target != NULL) {
temp = target;
target = target->nextWord;
free(temp);
temp = NULL; <-- optional
}
Your while loop was setting target to a node that was already freed, whereas in my excerpt, temp is reset to the next target node after every iteration, and then is subsequently freed.

C freeing multi-dimensional array inside a struct seems incorrect

I've seen another question for allocating and freeing multi-dimensional arrays, but I suspect that it does not free correctly. For testing I made this small code extracted from my main code.
I compiled it under MacOS X.10 with XCode or gcc 4.9 with same results:
Faulty code
It runs 200000 times and the memory consumption grows up to 20GB!:
#include <stdlib.h>
typedef struct{
int lonSize;
int latSize;
double **grid;
}raf09_grid_t;
static raf09_grid_t raf09_grid;
void free_raf09_grid() {
if (raf09_grid.grid != NULL) {
int i;
for (i = 0; i < raf09_grid.lonSize; ++i) {
free(raf09_grid.grid[i]);
}
free(raf09_grid.grid);
}
raf09_grid.latSize = 0;
raf09_grid.lonSize = 0;
}
void get_raf09_grid() {
int nbElLat=381;
int nbElLon=421;
raf09_grid.grid = malloc(nbElLon*sizeof(double*));
int it;
for(it=0;it<nbElLon;it++)
raf09_grid.grid[it] = malloc(nbElLat*sizeof(double));
int i,j;
for(i=0;i<420;i++) {
for(j=0;j<380;j++) {
raf09_grid.grid[i][j]=0.0;
}
}
}
int main (int argc, char *argv[]) {
int i=0;
for (i=0;i<20000;i++) {
get_raf09_grid();
free_raf09_grid();
}
return 0;
}
I'm newbie so I suspect that my freeing is not correct...
Corrected code
With your help I corrected my code, it is now corrects and takes only 10M in ram:
#include <stdlib.h>
typedef struct{
int lonSize;
int latSize;
double **grid;
}raf09_grid_t;
static raf09_grid_t raf09_grid;
void free_raf09_grid() {
if (raf09_grid.grid != NULL) {
int i;
for (i = 0; i < raf09_grid.lonSize; ++i) {
free(raf09_grid.grid[i]);
}
free(raf09_grid.grid);
}
raf09_grid.latSize = 0;
raf09_grid.lonSize = 0;
}
void get_raf09_grid() {
raf09_grid.latSize=381;
raf09_grid.lonSize=421;
raf09_grid.grid = malloc(raf09_grid.lonSize*sizeof(double*));
int it;
for(it=0;it<raf09_grid.lonSize;it++)
raf09_grid.grid[it] = malloc(raf09_grid.latSize*sizeof(double));
int i,j;
for(i=0;i<420;i++) {
for(j=0;j<380;j++) {
raf09_grid.grid[i][j]=0.0;
}
}
}
int main (int argc, char *argv[]) {
int i=0;
for (i=0;i<20000;i++) {
get_raf09_grid();
free_raf09_grid();
}
return 0;
}
Valgrind is an invaluable tool in tracing memory leaks. Compiling your source code with debug information, and running it with:
valgrind --leak-check=full -v ./a.out
will give the following summary:
==7033== HEAP SUMMARY:
==7033== in use at exit: 1,283,208,000 bytes in 421,000 blocks
==7033== total heap usage: 422,000 allocs, 1,000 frees, 1,286,576,000 bytes allocated
==7033==
==7033== Searching for pointers to 421,000 not-freed blocks
==7033== Checked 92,040 bytes
==7033==
==7033== 18,288 bytes in 6 blocks are possibly lost in loss record 1 of 2
==7033== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7033== by 0x400611: get_raf09_grid (grid.c:27)
==7033== by 0x4006A8: main (grid.c:39)
==7033==
==7033== 1,283,189,712 bytes in 420,994 blocks are definitely lost in loss record 2 of 2
==7033== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7033== by 0x400611: get_raf09_grid (grid.c:27)
==7033== by 0x4006A8: main (grid.c:39)
==7033==
==7033== LEAK SUMMARY:
==7033== definitely lost: 1,283,189,712 bytes in 420,994 blocks
==7033== indirectly lost: 0 bytes in 0 blocks
==7033== possibly lost: 18,288 bytes in 6 blocks
==7033== still reachable: 0 bytes in 0 blocks
==7033== suppressed: 0 bytes in 0 blocks
==7033==
==7033== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
--7033--
--7033-- used_suppression: 2 dl-hack3-cond-1
==7033==
==7033== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
The link to line 27 shows that there is a problem with this statement:
raf09_grid.grid[it] = malloc(nbElLat*sizeof(double));
You are allocating more memory here than is being freed later in the program.
Update the raf09_grid.lonSize variable in get_raf09_grid() to equal nbElLon, and it fixes the problem.
In general, every malloc should have a corresponding free. Once you know which malloc is leaking, then you can find the code that is supposed to free that variable, and debug from there.
Note: I reduced the loop from 20000 to 1000, but it will give you the same information.
After reading through yoiur question, here are a few suggestions:
In the code:
for(i=0;i<420;i++) {
for(j=0;j<380;j++) {
raf09_grid.grid[i][j]=0.0;
}
you are looping i and j for 420 and 380, while you've defined :
int nbElLat=381;
int nbElLon=421;
So, you never process the 420th iteration for the Longitudes. The same with missing out on the 380th loop for Latitude.
If that's a desirable thing, its fine, else you should fix it to something like this:
for(i=0;i<nbElLon;i++) { //better use macros or variable names than just plain magic numbers
for(j=0;j<nbElLat;j++) {
raf09_grid.grid[i][j]=0.0;
}
Second, in your free_raf09_grid() function, you use:
for (i = 0; i < raf09_grid.lonSize; ++i) {
but you haven't initialized that variable anywhere.
Perhaps in function get_raf09_grid() just before the declaration of int i,j do this:
raf09_grid.lonSize = nbElLon;
raf09_grid.latSize = nbElLat;
The third important one.
In the lines below:
raf09_grid.grid = malloc(nbElLon*sizeof(double*));
int it;
for(it=0;it<nbElLon;it++)
raf09_grid.grid[it] = malloc(nbElLat*sizeof(double));
you should check if the mallocs have returned success or not aka check for NULL.
your for loop uses lonSize as a parameter, but it doesn't get updated anywhere

Why does my implementation of a dynamic string array leak?

I need a string array which dynamically resizes when more items are added to it. I got the basic code working, but valgrind reports memory leaks.
The implementation which should work with static and dynamically allocated strings looks like this:
typedef struct {
char **items;
int num;
} StringArray;
StringArray* string_array_init() {
StringArray *arr = malloc(sizeof(StringArray));
arr->items = NULL;
arr->num = 0;
return arr;
}
void string_array_add(StringArray *arr, char *str, int str_len) {
void *new_items = realloc(arr->items, (arr->num + 1) * sizeof(char *));
arr->items = (char**)new_items;
arr->items[arr->num] = strndup(str, str_len);
arr->num++;
}
void string_array_cleanup(StringArray *arr) {
int i;
for (i = 0; i < arr->num ; i++) {
free(arr->items[i]);
}
free(arr);
}
int main() {
StringArray *arr = string_array_init();
string_array_add(arr, "item 1", strlen("item 1"));
string_array_add(arr, "item 2", strlen("item 2"));
string_array_add(arr, "item 3", strlen("item 3"));
string_array_cleanup(arr);
return 0;
}
Valgrind reports:
==31443== HEAP SUMMARY:
==31443== in use at exit: 12 bytes in 1 blocks
==31443== total heap usage: 7 allocs, 6 frees, 53 bytes allocated
==31443==
==31443== 12 bytes in 1 blocks are definitely lost in loss record 1 of 1
==31443== at 0x4025CCD: realloc (vg_replace_malloc.c:525)
==31443== by 0x80484A6: string_array_add (in ...)
==31443== by 0x8048593: main (in ...)
==31443==
==31443== LEAK SUMMARY:
==31443== definitely lost: 12 bytes in 1 blocks
==31443== indirectly lost: 0 bytes in 0 blocks
==31443== possibly lost: 0 bytes in 0 blocks
==31443== still reachable: 0 bytes in 0 blocks
==31443== suppressed: 0 bytes in 0 blocks
==31443==
Why is realloc leaking and how can I fix it? I thoght freeing every string separately and then freeing the struct would be enough, but I´m missing something.
You free the strings contained in arr->items, but you don't free arr->items itself. (You allocated it in string_array_add).
The problem is with this line:
arr->items = (char**)new_items;
You overwrite the old pointer. You need to realloc this pointer and not new_items.

Resources