2013-06-11 4 views
-3

Друзья, Я пытаюсь освободить память от массива указателей, как:бесплатно ведет к повреждению памяти

const gchar *strings[21]; 
strings[0] = malloc(strAuth) 
strings[0] = strAuth 
.... 
.... 
    int j=0; 
    while(j < 20){ 
     if (strlen(strings[j]) != 0) { 
    g_free((char*)strings[j]); 
    g_print("Cleaned:%d\n",j); 
     } 
     j++; 
     g_print("%d",j); 
    } 
//g_free((char*)strings); 

J гравюр Шифрование до 20, а затем дает

$ ./mkbib 
Cleaned:0 
1Cleaned:1 
2Cleaned:2 
34Cleaned:4 
56789101112Cleaned:12 
1314151617181920*** glibc detected *** ./mkbib: malloc(): memory corruption (fast): 0x0000000000a14e10 *** 

Любое объяснение (в C -novice)?

EDIT 1 Извините за глупую информацию, я избегал того, что такое strAuth, потому что это включает в себя библиотеку gtk (у меня плохой опыт по заданию конкретного вопроса, зависящего от библиотеки, в clc). Таким образом, код реальный выглядит:

strings[0] = g_malloc(strlen(gtk_entry_get_text(GTK_ENTRY(e->entry1)))); 
strings[0] = gtk_entry_get_text(GTK_ENTRY(e->entry1)); 

gtk_entry_get_text где имеет тип const gchar * Возможно, я впустую Ваше время с начальной должности. Пожалуйста помоги.

EDIT 2

const gchar *strings[21]; 
strings[0] = g_malloc(strlen(gtk_entry_get_text(GTK_ENTRY(e->entry1)))); 
strings[0] =g_strdup(gtk_entry_get_text(GTK_ENTRY(e->entry1))); 
........ 
int i=2; 
    while (i < 21) { 
     if (strlen(strings[i]) != 0) { 
    g_string_append_printf(tstring, ",\n\t%s=\"%s\"", 
     keyword[i], strings[i]); 
     g_free((char*)strings[i]); 
     strings[i]=NULL; 
     g_print("Cleaned:%d\n",i); 
     } 
     i++; 
} 
+0

Что is strAuth и почему вы передаете его в malloc (который принимает size_t)? –

+0

Что такое 'strAuth'? – AnT

+0

Мне удалось (возможно) его исправить. Пожалуйста, посмотрите на редактирование 2. Поскольку я не нашел способа проверить, действительно ли строки освобождены, прокомментируйте, если это выглядит лучше. – BaRud

ответ

4

Во-первых, это

strings[0] = malloc(strAuth) 
strings[0] = strAuth; 

неисправно. Какой тип strAuth? Как вам удалось использовать strAuth как аргумент malloc (т. Е. Размер), а затем сразу же в качестве правого размера присвоения? malloc s аргумент должен быть целым числом, в то время как strings[0] имеет тип указателя. Помимо того, что это полностью противоречиво, такой вид использования будет вызывать диагностические сообщения от компилятора. Вы просто игнорировали эти сообщения?

Если strAuth является строкой, и если вы пытаетесь выделить память для копии strAuth, то типичный идиома распределение памяти будет

strings[0] = malloc(strlen(strAuth) + 1); 

Во-вторых, почему вы даже пытаться присвоить что-нибудь strings[0] после malloc? Указатель в strings[0] является вашим единственным подключением к недавно выделенной памяти, которую вы должны лелеять и сохранять всеми способами. Вместо этого вы сразу же сжимаете этот указатель, назначая новое значение strings[0], превращая только что выделенную память в утечку памяти.

Опять же, если вы пытаетесь создать копию strAuth в strings[0], то типичный идиома будет

strings[0] = malloc(strlen(strAuth) + 1); 
strcpy(strings[0], strAuth); 

(конечно, в реальном коде нужно всегда помнить, чтобы проверить, удалось ли malloc или нет).

На многих платформах нестандартным strdup функция доступна, которая оборачивает точно выше функциональные возможности выделения, и-копии, а это означает, что указанные выше две строки могут быть заменены простой

strings[0] = strdup(strAuth); 

И, наконец, в-третьих , что такое g_free? Вы уверены, что это применимо к памяти, выделенной стандартом malloc (в отличие от, скажем, g_malloc). И даже если это будет применимо, все равно не рекомендуется смешивать подобные API. Если вы хотите выделить память по стандарту malloc (или strdup), тогда это хорошая идея придерживаться стандарта free для его освобождения.

2
strings[0] = malloc(strAuth) 
strings[0] = strAuth 

После выделения памяти для strings[0], вы перезаписать возвращаемый указатель с strAuth, который я не знаю, что это такое, но, вероятно, строка, которая не была выделена используя malloc() (или один из его родственников, например realloc()). И вы не можете освободить такой объект.

(и в любом случае:. Если strAuth является строка, а не вы должны выделить достаточно места для его длины (плюс один для завершающего NUL байт) вместо malloc(strAuth) кажется бессмысленным для меня)

0

Давайте добавим некоторые комментарии, чтобы помочь вам:

const gchar *strings[21];  // allocate an array of 21 pointers to gchar constants 
strings[0] = malloc(strAuth) // assign some memory (strAuth number of bytes) to the 
           // first pointer 
strings[0] = strAuth   // reassign the first pointer the value of strAuth 

Когда вы делаете назначение strAuth к strings[0] вы перезапись что malloc'd там в первую очередь. Так что если strAuth - это какой-то строковый литерал или что-то не malloc'd, тогда вызов на бесплатный действительно провалится. Вы можете освобождать только то, что было динамически распределено.

Так что вам нужно решить, хотите ли вы указывать указатели на постоянные строки в вашем массиве (и не делать malloc или бесплатно), или если вы хотите malloc/free, а затем скопируйте свои строки в массив.

Примечание вы звоните malloc() в сочетании с g_free()that's not a good idea.g_malloc() и g_free() больше, чем просто обертки вокруг free() и malloc(), и поэтому вы должны использовать их в качестве такого ... псевдокода объяснение:

if 
    g_malloc(strings[x]) 
    then 
    g_free(strings[x]) 
else if 
    strings[x] = malloc(y) 
    then 
    free(strings[x])