调用g_free()释放g_date_time_format()返回值触发无效指针错误原因
调用g_free()释放g_date_time_format返回值时触发free(): invalid pointer错误的原因
我通过当前系统时间生成日期字符串,按照GLib DateTime format文档说明,需要用g_free()释放g_date_time_format()的返回结果,但调用该函数时触发了free(): invalid pointer错误,请问这是什么原因?
代码示例
#include <glib.h> #include <stdio.h> int main(int argc, char *argv[]) { GDateTime *date_time = g_date_time_new_now_local(); gchar *date_time_string = g_date_time_format(date_time, "%H:%M:%S"); if (date_time_string == NULL) { g_print("it is null\n"); } else { g_print("%s\n",date_time_string); g_free(date_time_string); /* abort occurs here */ } g_free(date_time); return 0; }
程序输出
12:16:16 free(): invalid pointer Aborted (core dumped)
GDB调试信息
使用gdb ./a.out运行程序,终止后执行bt命令得到以下结果:
Starting program: logging/a.out [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". 12:38:00 free(): invalid pointer Program received signal SIGABRT, Aborted. __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737348770880) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737348770880) at ./nptl/pthread_kill.c:44 #1 __pthread_kill_internal (signo=6, threadid=140737348770880) at ./nptl/pthread_kill.c:78 #2 __GI___pthread_kill (threadid=140737348770880, signo=signo@entry=6) at ./nptl/pthread_kill.c:89 #3 0x00007ffff7c82476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #4 0x00007ffff7c687f3 in __GI_abort () at ./stdlib/abort.c:79 #5 0x00007ffff7cc9676 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff7e1bb77 "%s\n") at ../sysdeps/posix/libc_fatal.c:155 #6 0x00007ffff7ce0cfc in malloc_printerr (str=str@entry=0x7ffff7e19744 "free(): invalid pointer") at ./malloc/malloc.c:5664 #7 0x00007ffff7ce2a44 in _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at ./malloc/malloc.c:4439 #8 0x00007ffff7ce5453 in __GI___libc_free (mem=<optimized out>) at ./malloc/malloc.c:3391 #9 0x000055555555522f in main (argc=1, argv=0x7fffffffe028) at a.c:16
问题原因与修复
核心问题是释放GDateTime对象的方式错误:g_date_time_new_now_local()创建的GDateTime对象属于GLib的引用计数式对象,不能用g_free()直接释放,必须调用g_date_time_unref()来减少引用计数,当引用计数降为0时,对象才会被自动销毁。
你当前用g_free(date_time)直接释放GDateTime对象,会破坏GLib内部的内存管理结构——要么是g_date_time_format()返回的字符串和GDateTime对象的内存区域存在关联,要么是GDateTime被错误释放后堆内存状态被破坏,最终导致后续对date_time_string调用g_free()时触发指针校验错误。
修复后的代码如下:
#include <glib.h> #include <stdio.h> int main(int argc, char *argv[]) { GDateTime *date_time = g_date_time_new_now_local(); gchar *date_time_string = g_date_time_format(date_time, "%H:%M:%S"); if (date_time_string == NULL) { g_print("it is null\n"); } else { g_print("%s\n",date_time_string); g_free(date_time_string); } g_date_time_unref(date_time); // 替换为正确的释放方式 return 0; }
另外需要确认编译时是否正确链接GLib库,编译命令应类似:
gcc -o a.out a.c `pkg-config --cflags --libs glib-2.0`
确保使用GLib提供的内存管理函数和库实现一致,避免因链接错误导致的内存管理不兼容问题。
内容的提问来源于stack exchange,提问作者9-Pin
相关产品推荐
相关产品推荐

