-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 新手)?

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

where gtk_entry_get_textis of type const gchar * 可能我在最初的帖子上浪费了你的时间。请帮忙。

编辑 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++;
 }
4

3 回答 3

4

首先,这

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

肯定坏了。是什么类型的strAuth?您是如何设法将其strAuth用作(即大小)的参数malloc,然后立即用作分配的右手大小?mallocs 参数必须是整数,而strings[0]具有指针类型。除了完全自相矛盾之外,这种用法还会触发编译器的诊断消息。你只是忽略了那些消息吗?

IfstrAuth是一个字符串,并且如果您尝试为 的副本分配内存strAuth,那么典型的内存分配习惯用法是

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

其次,您为什么还要尝试将任何内容分配给strings[0]after malloc?in 的指针strings[0]是你与新分配的内存的唯一连接,你应该珍惜和保护它。相反,您立即通过为 分配一个新值来破坏该指针,从而strings[0]将您刚刚分配的内存变成内存泄漏。

同样,如果您尝试创建strAuthin的副本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以释放它。

于 2013-06-11T18:18:34.263 回答
2
strings[0]  = malloc(strAuth)
strings[0]  = strAuth

在为 分配内存后strings[0],您用 覆盖返回的指针strAuth,我不知道它是什么,但可能是一个未使用分配的字符串malloc()(或其亲属之一,如realloc())。你不能释放这样的对象。

(无论如何:如果strAuth是一个字符串,你不应该为它的长度分配足够的空间(加上一个用于终止 NUL 字节)吗?malloc(strAuth)对我来说似乎很荒谬。)

于 2013-06-11T18:18:30.343 回答
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

当您执行 to 的分配时strAuthstrings[0]您首先会覆盖 malloc 的内容。因此,如果strAuth是一些字符串文字或不是 malloc 的东西,那么对 free 的调用确实会失败。您只能释放已动态分配的内容。

因此,您需要决定是否要将指针粘贴到数组中的常量字符串(并且不要 malloc 或 free),或者是否要 malloc/free,然后将字符串复制到数组中。

请注意,您malloc()同时调用这不是一个好主意。并且不仅仅是包装器,所以你应该这样使用它们......伪代码解释:g_free() 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])
于 2013-06-11T18:29:18.090 回答