为什么我索引一个 Garray 时少了一个字符?

Why is there one char missing when I index a Garray?

我 运行 这段代码是我为 GUI 程序编写的,但我遇到了一个奇怪的错误,其中总是按顺序缺少一个字符。此代码已简化。

#include <gtk/gtk.h>

int main()
{
    GArray *array = g_array_new(FALSE, FALSE, 1000); /* I create the array */

    int i; /* An iterator used in the for loop. */
    char *question = "What does hypersomatic mean?"; 

    /* The insertion loop. */
    for (i = 0; i < 10; i++)
    {
        /* I pass the array along, the data, and the number of elements to insert. */
        array = g_array_append_vals(array, question, 1);
    }

    /* The reading loop */
    for (i = 0; i < 10; i++)
    {
        /* I pass along the array, the element type (gchar is correct, I think), and the index of the element. */
        char *what_is_this = &g_array_index(array, gchar, i);
        printf("%s\n", what_is_this);
    }
    return 0;
}

我编译了这个:gcc `pkg-config gtk+-3.0 --libs --cflags` main.c

这是输出:

超体是什么意思?
hypersomatic 是什么意思?
at hypersomatic 是什么意思?
t hypersomatic 是什么意思?
hypersomatic 是什么意思?
oes hypersomatic 是什么意思?
es hypersomatic 是什么意思?
s hypersomatic 是什么意思?
hypersomatic 是什么意思?

这是什么意思?

您正在创建一个 GArray,每个元素的长度为 1000 字节,但是当您读取它时,您告诉 g_array_index() 每个元素是 sizeof(gchar) 字节长(即 1 字节长)。所以 g_array_index() 返回指向数组数据块中字符串第一次出现的字节 0..10 的指针。

如果你想打印出每个元素的全部,你的代码需要修改为:

#include <gtk/gtk.h>

typedef gchar my_element[1000];

…

    GArray *array = g_array_new(FALSE, FALSE, sizeof (my_element)); /* I create the array */

…

        char *what_is_this = &g_array_index(array, my_element, i);

…

这定义了数组元素的类型,因此代码可以一致地引用它的大小。


在现代代码中使用可变长度字符串比使用固定长度字符串更为典型。这些数组元素中的每一个都是 1KB 长,即使存储在其中的字符串只有 29 个字节长 — 因此每个元素中分配的内存的 97% 都被浪费了。

使用固定长度的字符串也会增加非常长的字符串(大于 1000 字节长)溢出分配的可能性,周围的代码可能没有为此做好准备。

通常,使用 GLib 的代码将使用 GPtrArray 来存储可变长度字符串的元素,分配有类似 g_strdup()g_strdup_printf().

的内容

您可能需要考虑更改您的代码来执行类似的操作。但是,我不知道你想要实现的目标的完整背景,所以这个建议可能不相关。