【问题标题】:Why is there one char missing when I index a Garray?为什么在索引 Garray 时缺少一个字符?
【发布时间】:2021-09-12 01:01:34
【问题描述】:

我运行了我为 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 是什么意思?
超体是什么意思?
t 是什么意思?
hypersomatic 是什么意思?
oes 超体型是什么意思?
es 超体是什么意思?
s 超体的意思是什么?
超体平均?

这是什么意思?

【问题讨论】:

  • 你为什么把1000传给g_array_new!?为什么在存储char* 时会读取gchar
  • 这是每个元素的大小,我想我可以用 29 代替。这就是字符串的大小。

标签: arrays missing-data glib


【解决方案1】:

您正在创建一个 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() 之类的东西。

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

【讨论】:

  • 那么,我该怎么做呢?
  • 我不太清楚你到底想做什么。
  • 我怎么能打印出数组 10 次(或更多),并且开头没有字符消失。
  • 我已经编辑了我的答案,以展示如何更改代码以一致地将元素引用为每个 1000 字节长。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 2023-04-03
  • 1970-01-01
  • 2022-06-10
相关资源
最近更新 更多