Valgrind definitely lost block of memory - c

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;
}

Related

Memory Leak : Possible memory while scan through valgrind

I saw some random behavior while scanning my code through Valgrind. i have freed all possible memory blocks still I seeing Valgrind say 1 block is not properly freed.
Objective: Creating the 3 level json by using cJSON.c then in the second block modified the json format.
#include<stdio.h>
#include<stdlib.h>
#include"cJSON.h"
int main () {
cJSON *root = NULL, *root1 = NULL , *arrays = NULL, *array = NULL;
root = cJSON_CreateObject();
root1 = cJSON_CreateObject();
arrays = cJSON_CreateArray();
cJSON_AddItemToObject(root,"check",root1);
cJSON_AddItemToObject(root1, "innercheck",cJSON_CreateString("just to check"));
cJSON_AddItemToObject(root1, "array", arrays);
cJSON_AddItemToArray(arrays, array = cJSON_CreateObject());
cJSON_AddItemToObject(array, "innnerarray", cJSON_CreateNumber(1));
char *out = NULL;
printf("===================================================\n");
out = cJSON_Print(root);
printf("%s\n", out);
/* further operation now going to extract the value from json and readd new key */
cJSON *json_param = NULL, *exe1 = NULL , *exe2 = NULL;
json_param = cJSON_Parse(out);
exe1 = cJSON_GetObjectItem(json_param , "check");
cJSON_DeleteItemFromObject(exe1, "check");
exe2 = cJSON_CreateObject();
cJSON_AddItemToObject(exe2, "test", exe1);
char *out2 = NULL;
out2 = cJSON_Print(exe2);
printf("====================================================\n");
printf("%s\n", out2);
if(root) {
cJSON_Delete(root);
root = NULL;
}
if(json_param) {
cJSON_Delete(json_param);
json_param = NULL;
}
if(out) {
free(out);
out = NULL;
}
if(out2) {
free(out2);
out2 = NULL;
}
return 0;
}
Valgrind scan report :
==23708== Memcheck, a memory error detector
==23708== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==23708== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==23708== Command: ./object
==23708==
===================================================
{
"check": {
"innercheck": "just to check",
"array": [{
"innnerarray": 1
}]
}
}
====================================================
{
"test": {
"innercheck": "just to check",
"array": [{
"innnerarray": 1
}]
}
}
==23708==
==23708== HEAP SUMMARY:
==23708== in use at exit: 64 bytes in 1 blocks
==23708==
> total heap usage: 29 allocs, 28 frees, 2,661 bytes allocated
==23708==
==23708== 64 bytes in 1 blocks are definitely lost in loss record 1 of 1
==23708== at 0x4C2FDFB: malloc (vg_replace_malloc.c:309)
==23708== by 0x108F47: cJSON_New_Item (cJSON.c:214)
==23708== by 0x10C9F8: cJSON_CreateObject (cJSON.c:2410)
==23708==
> by 0x108BFA: main (object.c:35)
==23708==
==23708== LEAK SUMMARY:
==23708== definitely lost: 64 bytes in 1 blocks
==23708== indirectly lost: 0 bytes in 0 blocks
==23708== possibly lost: 0 bytes in 0 blocks
==23708== still reachable: 0 bytes in 0 blocks
==23708== suppressed: 0 bytes in 0 blocks
==23708==
==23708== For lists of detected and suppressed errors, rerun with: -s
==23708== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
I have freed all the possible memory block but unable to get why still I am getting 1 block is not properly free.
It seems there are two problems in your code.
Firstly, you need to release the exe2 object (which you had allocated using cJSON_CreateObject()) before exiting.
cJSON_Delete(exe2);
Secondly ... You need to detach the check object from json_param before adding it to the exe2 object. Otherwise you will have a double free when you call cJSON_Delete(exe2) - the library will attempt to free the same object twice (since the same object will have been attached as a child to more than one object).
So change
exe1 = cJSON_GetObjectItem(json_param, "check");
cJSON_DeleteItemFromObject(exe1, "check");
to simply
exe1 = cJSON_DetachItemFromObject(json_param, "check");
Note that I removed the line cJSON_DeleteItemFromObject(exe1, "check"); - as it is redundant as far as I can tell (unless you meant to remove the innercheck element instead).

alloc and free of 2d array

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 );

Two different memory errors depending on where I allocate the memory

For my C program I have tried to allocate memory for a double array(ssi) which I then access in another function (spslicer). If I allocate this memory before I call a different function (kpmdos) which should be unrelated I get the error:
*** glibc detected *** ./SpecSli.ex: double free or corruption (!prev): 0x0000000000a86e40 ***
and if I allocate it after I get the error:
malloc.c:3830: _int_malloc: Assertion `(unsigned long)(size) >= (unsigned long)(nb)' failed.
Based on this I think that I did something wrong in kpmdos when I allocated the memory but I cannot see anything wrong:
void kpmdos(csptr A, int Mdeg, double nvec, double ctr, double wid, int n, double *mu){
// initialize variables
double *w = malloc(n*sizeof(double));
//free(w);
fill_rand(n, w);
double *v = malloc(n*sizeof(double));
divide_array(w, norm(w, n), v, n);
double *vkm1 = malloc(n*sizeof(double));
fill(n, 0, vkm1);
double *vk = malloc(n*sizeof(double));
memcpy(vk,v, n*sizeof(double));
double *temp = malloc(n*sizeof(double));
double *vkp1 = malloc(n*sizeof(double));
double thet = pi/(Mdeg+1);
double a1 = 1/(Mdeg+2.0);
double a2 = sin(thet);
double jac;
double scal;
Then I do some other coding with no memory allocation.
free(w);
free(vkp1);
free(vkm1);
free(temp);
free(vk);
free(v);
}
The output using valgrind when it is allocated before the function is:
> > ==7045== HEAP SUMMARY:
> ==7045== in use at exit: 46,452 bytes in 235 blocks
> ==7045== total heap usage: 351 allocs, 116 frees, 66,700 bytes allocated
> ==7045==
> ==7045== LEAK SUMMARY:
> ==7045== definitely lost: 22,331 bytes in 146 blocks
> ==7045== indirectly lost: 0 bytes in 0 blocks
> ==7045== possibly lost: 0 bytes in 0 blocks
> ==7045== still reachable: 24,121 bytes in 89 blocks
> ==7045== suppressed: 0 bytes in 0 blocks
> ==7045== Rerun with --leak-check=full to see details of leaked memory
> ==7045==
> ==7045== For counts of detected and suppressed errors, rerun with: -v
> ==7045== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Please let me know if you know the problem or if you need more information.
Thank you all for your help. I finally figured out most of it. During my coding which I did not post I had a function which would change all the variables in an array to something different and for this function I was inputting the wrong array size.

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.

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