免费导致内存损坏

时间:2013-06-11 18:15:43

标签: c arrays memory-corruption

友 我试图从指针数组中释放内存:

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

其中gtk_entry_get_text的类型为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++;
 }

3 个答案:

答案 0 :(得分:4)

首先,这个

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

彻底打破了。 strAuth的类型是什么?你是如何设法使用strAuth作为malloc(即大小)的参数,然后立即作为任务的右手大小? malloc的参数必须是整数,而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来释放内存。

答案 1 :(得分:2)

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

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

(无论如何:如果strAuth是一个字符串,那么你不应该为其长度(加上一个终止NUL字节)分配足够的空间吗?malloc(strAuth)对我来说似乎毫无意义。)

答案 2 :(得分: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。因此,如果strAuth是一些字符串文字或某些不是malloc'd,那么对free的调用确实会失败。您只能释放动态分配的内容。

所以你需要决定是否要在数组中指向常量字符串(并且不要malloc或free),或者你想要malloc / free然后将字符串复制到数组中。

请注意,您与malloc() g_free() that's not a good idea.g_malloc()一起呼叫g_free()不仅仅是围绕free()和{{}}的包装{3}}所以你应该使用它们......伪代码说明:

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