【问题标题】:C/Glib, am I truncating this gchar array properly?C/Glib,我是否正确截断了这个 gchar 数组?
【发布时间】:2013-10-19 00:10:19
【问题描述】:

我试图重构/修复一个函数,我是否正确地进行了截断?如果不是,这一般应该怎么做?特别想知道潜在的泄漏。

void process_entry(GMenuTreeEntry *entry)
{
    char *name = g_strdup (gmenu_tree_entry_get_name(entry));
    char *exec = g_strdup (gmenu_tree_entry_get_exec(entry));
    int i;

    for (i = 0; i < strlen(exec) - 1; i++) {
        if (exec[i] == '%')
        {
            switch (exec[i+1]) {
                case 'f': case 'F':
                case 'u': case 'U':
                case 'd': case 'D':
                case 'n': case 'N':
                case 'i': case 'c': case 'k': case 'v': case 'm':
                    exec[i-1] = '\0';
                    i++;
                    break;
            }
        }
    }

    g_printf("<item label=\"%s\">\n", g_strjoinv("&amp;", g_strsplit(name,"&",0))),
    g_printf("<action name=\"Execute\"><command>%s</command></action>\n", exec),
    g_printf("</item>\n");

    g_free(name);
    g_free(exec);
}

这是一些 GPL 代码,非常感谢您的帮助。总的来说,我对 C 语言还是很陌生,而 glib 确实是全新的。

【问题讨论】:

  • 当然你会在提交之前对这个函数进行单元测试。不要只满足于这些,但基本测试必然会针对 null、empty、“%a”、“a%”、“a”、“%”进行测试。我希望其中三个会出现段错误。是的,当然有泄漏,就在你认为有泄漏的地方。但是,是的,插入 '\0' 是截断 C 字符串的完美方式。
  • ptomato 很好地回答了截断部分。至于泄漏,您正在泄漏 g_strjoinv 和 g_strsplit 的返回值。您应该将结果保存到一个临时变量中,然后使用该值调用 g_printf,然后对它们调用 g_free 和 g_strfreev。

标签: c string free glib


【解决方案1】:

gcharchar 完全相同,因此您在此处执行的操作也适用于常规 C 字符串。

当您在字符串上调用free()g_free() 时,它不会计算strlen() 来确定要释放多少内存;无论最初在该地址分配多少内存,它都会释放。否则,您永远无法释放未在某处指定其分配内存长度的指针。所以截断字符串是安全的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-07
    • 2018-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    相关资源
    最近更新 更多