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

标签 c data-structures valgrind glib

它获取已登录系统的用户的详细信息并打印其详细信息并将其存储在适当的数据结构中并最终显示。 这是我写的代码。输出是正确的,但我在 valgrind 检查中得到“肯定丢失”和“间接丢失”。 尝试了很多检查泄漏。 谁能帮我清除它们。如果他们告诉我们在编写 prgoram 本身时如何避免这种情况,那将会很有用。 包含所有必要的头文件

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

关于c - 使用 GLib 包模拟 linux 命令 “who” 的行为 - Valgrind 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35424355/

相关文章:

c - 为什么 inet_aton 返回的十六进制数是倒序的?

C编程-如何计算单词中字母的重复次数

c - 在父进程结束之前,linux 是否永远不会结束子进程?

c - 链表查询

c++ - 无法访问映射中已初始化结构的内容

c - 在C中使用calloc为char数组分配内存时如何避免 'possibly lost'内存

android - Valgrind 无法创建临时文件

c++ - 如何使用c函数计算文本文件中的单词数

algorithm - 包含不需要的单词的文档检索

c - Valgrind 通知我 C 中存在内存泄漏,我很确定我已修复该问题