Невозможно освободить результат из g_date_time_format()

В следующем коде я создаю строку даты из текущего системного времени. В документации для формата GLib DateTime сказано, что мне нужно освободить результат с помощью g_free(). Когда я пытаюсь это сделать, я получаю сообщение об ошибке 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 ./a.out.

После того, как программа прервалась, я сделал bt внутри gbd. Вот результат.

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

Можете ли вы добавить трассировку стека?

Raildex 01.09.2024 18:32

Для g_date_time_new_now_local вам нужно освободить g_date_time_unref()

CGi03 01.09.2024 18:39

Как упоминает @CGi03, использование g_date_time_unref() устранило состояние ошибки. Valgrind сообщает об отсутствии утечек памяти. Спасибо!.

9-Pin 01.09.2024 18:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Возвращаемое значение g_date_time_new_now_local() учитывает ссылки, поэтому вам следует g_date_time_unref() освободить его:

#include <glib.h>
#include <stdio.h>

int main() {
    GDateTime *date_time = g_date_time_new_now_local();
    if (!date_time)
        return 1;
    gchar *date_time_string = g_date_time_format(date_time, "%H:%M:%S");
    g_print("%s\n", date_time_string ? date_time_string : "it is null\n");
    g_free(date_time_string);
    g_date_time_unref(date_time);
}

Спасибо за ваш ответ!

9-Pin 02.09.2024 20:12

Хотя возникает вопрос: как мы узнаем, какие объекты освобождаются с помощью g_free() и unref()? Документация GTK не всегда ясна.

9-Pin 02.09.2024 20:13

@9-Pin Я советую вам сообщать о дефектах в документации, если они не ясны. Вы также можете посмотреть исходный код glib, если хотите быть уверенным.

Allan Wind 02.09.2024 22:24

Другие вопросы по теме