使用 GLib 包模拟 linux 命令“who”的行为 - Valgrind 错误

Simulating the behavior of the linux command “who” using GLib package - Valgrind error

获取系统登录用户的详细信息,打印他们的详细信息,存储在合适的数据结构中,最后展示。 这是我写的代码。输出是正确的,但我在 valgrind 检查中得到 'definitely lost' 和 'indirectly lost'。 试了很多检查泄漏。 谁能帮我清除它们。如果他们告诉我们在编写程序本身时如何避免这种情况,那将很有用。 包含所有必要的头文件

void disp(gpointer key, gpointer value, gpointer userdata)
{
printf("%-10s",(char*)key);
g_slist_foreach((GSList*)value, (GFunc)displ, NULL);
printf("\n");
g_free(key);
g_slist_free((GSList*)value);
}

void displ(gpointer value, gpointer userdata)
{
printf("%-25s ", (char *)value);
g_free(value);
}

int main(int argc, char *argv[])
{
if(argc > 1)
{
    printf("Too many input arguments. \n");
    exit(1);
}

GHashTable* hash = NULL;
hash = g_hash_table_new(g_str_hash, g_str_equal);
GSList* list = NULL;

struct utmpx *ret = NULL;
struct passwd *uentry = NULL;
char *id = NULL;
char *name = NULL;
char *hostid = NULL;

while((ret = getutxent())!= NULL)
{
    if(USER_PROCESS == ret->ut_type)
    {       
        /*fetch userid for this user*/
        uentry = getpwnam(ret->ut_user);
        if (NULL == uentry)
        {
            printf("No user found. \n");
            return 0;
        }
        else 
        {   
            /* Create new list for each user */
            list = NULL;
            id = strdup(ret->ut_user);
            name = strdup(uentry->pw_gecos);
            hostid = strdup(ret->ut_host);
            list = g_slist_append(list, name);
            list = g_slist_append(list,hostid);

            g_hash_table_insert(hash, id, list);
                        }
    }
}
/* printing the details of respective users */
g_hash_table_foreach(hash, (GHFunc)disp, NULL);
/*freeing memory created for Hash Table */
g_hash_table_destroy(hash);
return 0;
}

为了释放 Glib 使用的所有内存,您必须使用它的特定函数来执行此操作,因为 Glib 使用引用计数方法来释放对象。我按如下方式更改了您的代码,并且已成功释放所有使用的内存。

#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <utmpx.h>
#include <pwd.h>
#include <sys/types.h>

void displ(gpointer value, gpointer userdata)
{
    printf("%-25s ", (char *) value);
}

void dell(gpointer value)
{
    g_free(value);
}

void del_list(gpointer value)
{
    g_slist_free_full((GSList*)value, (GDestroyNotify)dell);
}

int disp_del(gpointer key, gpointer value, gpointer userdata)
{
    printf("%-10s",(char*)key);
    g_slist_foreach((GSList*)value, (GFunc)displ, NULL);
    printf("\n");
    return TRUE;
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        printf("Too many input arguments. \n");
        exit(1);
    }

    GHashTable* hash = NULL;
    hash = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)del_list);
    GSList* list = NULL;

    struct utmpx *ret = NULL;
    struct passwd *uentry = NULL;
    char *id = NULL;
    char *name = NULL;
    char *hostid = NULL;

    while ((ret = getutxent())!= NULL) {
        if(USER_PROCESS == ret->ut_type) {
            /* fetch userid for this user */
            uentry = getpwnam(ret->ut_user);
            if (NULL == uentry) {
                printf("No user found. \n");
                return 0;
            } else {
                /* Create new list for each user */
                list = NULL;
                id = strdup(ret->ut_user);
                name = strdup(uentry->pw_gecos);
                hostid = strdup(ret->ut_host);
                list = g_slist_append(list, name);
                list = g_slist_append(list, hostid);
                g_hash_table_insert(hash, id, list);
            }
        }
    }
    /* printing the details of respective users */
    g_hash_table_foreach_remove(hash, (GHRFunc)disp_del, NULL);
    /*freeing memory created for Hash Table */
    g_hash_table_remove_all(hash);
    g_hash_table_destroy(hash);
    return 0;
}