I have a GList which contains a collection of GSList. This GSlist contains a collection of GString. When I free the whole GList, I get segmentation fault.
Now check the following code.
GList *m_rows = NULL;
m_rows = mysql_multiple_rows(mysql, sql1->str);
g_list_foreach(m_rows, mysql_storage_load_settings, &data);
mysql_free_multiple_rows(m_rows); /// <----------------------- works just fine
m_rows = mysql_multiple_rows(mysql, sql2->str);
if(g_list_length(m_rows)>0){
g_list_foreach(m_rows, mysql_storage_load_accounts, &data);
mysql_free_multiple_rows(m_rows); /// <----------------------- Segmentation fault!
}else{
fprintf(stderr, "\e[31m\tUser has no account!\e[0m");
}
So m_rows are only allocated using g_string_new(), g_slist_prepend() and g_list_prepend(). g_string_new() creates new GString and added to a GSList. all the resultant GSList then get added to GList. It happens in mysql_multiple_rows function.
They are free'd using mysql_free_multiple_rows. This function just does the reverse.
See the clean up functions.
static void mysql_free_multiple_rows(GList *table){
g_list_free_full(table, mysql_free_single_row);
}
static void mysql_free_single_row(gpointer data){
g_slist_free_full(data, msyql_free_single_row_field); // data here is GSlist
}
static void msyql_free_single_row_field(gpointer data){
g_string_free(data, TRUE); // data here is GString actually
}
Could anyone tell me why I am getting this error? As both the memory allocation and de-allocation sequence are same I have no clue why its happening.
Valgrind output
Source file
Looking at the code, you seem to be freeing password in mysql_storage_load_accounts(). However, I don't see any special handling for it, so my guess would be that it gets freed twice.
Related
I am using json-c library to send json-object to client.And I notice there is no native function to release the memory which json_object_to_json_string allocate.Does the library release it automaticlly? OR I have to "free(str)" to avoid memory leak?
I tried to read its source code but it makes me unconscious...So anybody know this?
It seems that you don't need to free it manually.
I see that this buffer comes from within the json_object (see the last line of this function):
const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
{
if (!jso)
return "null";
if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
return NULL;
printbuf_reset(jso->_pb);
if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
return NULL;
return jso->_pb->buf;
}
The delete function frees this buffer:
static void json_object_generic_delete(struct json_object* jso)
{
#ifdef REFCOUNT_DEBUG
MC_DEBUG("json_object_delete_%s: %p\n",
json_type_to_name(jso->o_type), jso);
lh_table_delete(json_object_table, jso);
#endif /* REFCOUNT_DEBUG */
printbuf_free(jso->_pb);
free(jso);
}
It is important to understand that this buffer is only valid while the object is valid. If the object reaches 0 reference count, the string is also freed and if you are using it after it is freed the results are unpredictable.
cJSON memory leak is a post where a memory leak occured. But the problem n this case is the cJSON_Print() function.
I did not even use this function (have commented it for the time being) and have still a memory leakage. My ode looks like this
void myFunc(cJSON* ptr)
{
/*some code */
// I have used some sint32 numbers from another library for simplicity
// i will use int
int num = 30
cJSON_AddItemToArray(pt_data,cJSON_CreateNumber(num));
}
int main()
{
cJSON *root =cJSON_CreateObject();
cJSON *pt_PPC= cJSON_CreateArray();
cJSON_AddItemToObject(root,"PowerPC",pt_PPC);
cJSON *pt_data = cJSON_CreateArray();
cJSON_AddItemToArray(pt_PPC,pt_data);
int i;
for(i=0;i<10;i++)
myFunc(pt_PPC);
cJSON_Delete(root);
return 0;
}
The memory increases with time.
Any suggestions?
I've tried your code in VS2015 and found that your myFunc function does not even compile! The function cJSON_AddItemToObject takes three parameters and num is not even defined.
I tried with the following code:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include "cJSON.h"
void myFunc(cJSON* ptr)
{
/*some code */
cJSON_AddItemToObject(ptr, "Item", cJSON_CreateNumber(10.0));
}
int main()
{
cJSON *root = cJSON_CreateObject();
cJSON *pt_PPC = cJSON_CreateObject();
cJSON_AddItemToObject(root, "PowerPC", pt_PPC);
myFunc(pt_PPC);
cJSON_Delete(root);
_CrtDumpMemoryLeaks();
}
I enabled memory leak debugging (Link to Article) and used _CrtDumpMemoryLeaks() to print the possible memory leaks if any (to the debug output window).
There were no memory leaks detected.
Your code is not complete and has syntax errors so it's not possible to tell where the problem exactly is by looking at it.
Anyway it's most likely you're creating a JSON object (somewhere) and forgetting to add it to the root object or any of its descendants. When the root object is deleted the un-connected elements are not deleted and leaks memory.
Hope this helps.
I have found the problem. The problem is still somehow in the cJSON lib. Inside a function i am doing something like this.
uint8 *arr;
arr = (uint8 *)malloc(t_DataVariableInfo.s32_Size);
getvariables(&arr); // this function gets some variables from a datapool
//pt_data is the pointer of cJSON where this number has to be added
cJSON_AddItemToArray(pt_data,cJSON_CreateNumber(arr[i]));
free(arr);
Now because of some reason arr could not be freed. The cJSON_CreateNumber() function is maybe doing some changes in it. I got it to work by doing this
uint8 *arr;
arr = (uint8 *)malloc(t_DataVariableInfo.s32_Size);
uint8 *address = arr;
getvariables(&arr); // this function gets some variables from a datapool
//pt_data is the pointer of cJSON where this number has to be added
cJSON_AddItemToArray(pt_data,cJSON_CreateNumber(arr[i]));
free(address);
Thanks for the help. Sorry i could not post all the code. Is this a problem of cJSON_CreateNumber()??
void* password_cracker_thread(void* args) {
cracker_args* arg_struct = (cracker_args*) args;
md5hash* new_hash = malloc (sizeof(md5hash));
while(1)
{
char* password = fetch(arg_struct->in);
if(password == NULL )
{
deposit(arg_struct->out,NULL);
free(new_hash);
pthread_exit(NULL);
}
compute_hash(password,new_hash);
if(compare_hashes(new_hash,(md5hash**)arg_struct->hashes,arg_struct->num_hashes) != -1)
{
printf("VALID_PASS:%s \n",password);
deposit(arg_struct->out,password);
}else{
free(password);
}
}
}
This is a part of a program, where you get char* passwords from a ringbuffer, calculate md5 and compare them and push them into the next buffer if valid.
My problem is now, why can't I free those I don't need?
The whole program will stop if I try to and if I don't, I get memory leaks.
"You", and by this I mean your program, can only free() storage that was got from malloc()-and-friends, and only in the granularity it was got, and only once per chunk of storage.
In the code you show here, you're attempting to free() something got from fetch(). Since we can't see the definition of that function and you have not provided any documentation of it, our best guess is that
fetch() gives you a pointer to something other than a whole chunk
got from malloc()-et-al; and/or
some other part of the program not
shown here free()s the relevant chunk itself.
My impression from the gdk docs is that gdk_color_copy allocates memory:
Makes a copy of a color structure. The result must be freed using
gdk_color_free().
The future-version gdk_rgba_copy clearly does:
A newly allocated GdkRGBA, with the same contents as rgba
Nevertheless I am encountering memory errors in my code with the following (my_struct.color is a GdkColor *, initialized to NULL):
if (my_struct.color != NULL) {
gdk_color_free(my_struct.color);
}
my_struct.color = gdk_color_copy(color);
And the following appears to work:
if (my_struct.color == NULL) {
my_struct.color = malloc(sizeof(GdkColor));
}
memcpy(my_struct.color, color, sizeof(GdkColor));
gdk_color_copy uses g_slice_new to allocate memory as can be seen in the source.
Using g_free instead of gdk_color_free or g_slice_free will cause errors. This can be verified by compiling with G_SLICE=always-malloc which will cause g_slice_new to use malloc calls instead and the corruptions will disappear.
I am working on a fairly simple application written in C with GTK+ that is leaking memory badly. It has a few basic functions on timers that check the clock and poll an external networked device, parsing the string returned. The application runs on a small touch panel, and through TOP I can watch the available memory be eaten up as it runs.
I'm pretty new to C, so not surprised that I'm doing something wrong, I just can't seem to figure out what. I've been trying to use Valgrind to narrow it down, but honestly the output is a little over my head (10k+ line log file generated from running the application less than a minute). But in digging through that log I did find some functions repeatedly showing up with permanently lost blocks, all using some similar structure.
Example 1:
This is a short function that gets called when an option is selected. The last line with the g_strdup_printf is the one called out by Valgrind. select_next_show and select_show_five_displayed are both global variables.
static void show_box_five_clicked ()
{
g_timer_start(lock_timer);
gtk_image_set_from_file (GTK_IMAGE(select_show_1_cb_image), "./images/checkbox_clear.png");
gtk_image_set_from_file (GTK_IMAGE(select_show_2_cb_image), "./images/checkbox_clear.png");
gtk_image_set_from_file (GTK_IMAGE(select_show_3_cb_image), "./images/checkbox_clear.png");
gtk_image_set_from_file (GTK_IMAGE(select_show_4_cb_image), "./images/checkbox_clear.png");
gtk_image_set_from_file (GTK_IMAGE(select_show_5_cb_image), "./images/checkbox_checked.png");
select_next_show = g_strdup_printf("%i",select_show_five_displayed);
}
Example 2:
This is another function that gets called often and came up a lot in the Valgrind log. It takes the incoming response from the networked device, parses it into two strings, then returns one.
static gchar* parse_incoming_value(gchar* incoming_message)
{
gchar *ret;
GString *incoming = g_string_new(incoming_message);
gchar **messagePieces = g_strsplit((char *)incoming->str, "=", 2);
ret = g_strdup(messagePieces[1]);
g_strfreev(messagePieces);
g_string_free(incoming, TRUE);
return ret;
}
In all the cases like these which are causing problems I'm freeing everything I can without causing segmentation faults, but I must be missing something else or doing something wrong.
UPDATE:
To answer questions in comments, here is an example (trimmed down) of how I'm using the parse function and where the return is freed:
static void load_schedule ()
{
...other code...
gchar *holder;
gchar *holder2;
holder = read_a_line(schedListenSocket);
holder2 = parse_incoming_value(holder);
schedule_info->regShowNumber = holder2;
holder = read_a_line(schedListenSocket);
holder2 = parse_incoming_value(holder);
schedule_info->holidayShowNumber = holder2;
...other code....
g_free(holder);
g_free(holder2);
}
Any help is greatly appreciated!!
It looks like you free 'ret' once when calling g_free(holder2), but you've done multiple allocations for that one free - you call parse_incoming_value multiple times, each time causing an allocation, but you only free once right at the end.
As you copy the holder2 pointer into schedule_info elements each time, they actually have the "leaked" memory at the end.
If you do not free holder2 anywhere, but just free all the elements in schedule_info at the end of the code. I presume that shows no leak?
e.g.
holder2 = <result of dynamic alloc>;
schedule_info->a = holder2;
...
holder2 = <result of dynamic alloc>;
schedule_info->b = holder2;
...
// instead of g_free(holder2) at the end, do this...
g_free(schedule_info->a);
g_free(schedule_info->a);