为什么我索引一个 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()
.
的内容
您可能需要考虑更改您的代码来执行类似的操作。但是,我不知道你想要实现的目标的完整背景,所以这个建议可能不相关。
我 运行 这段代码是我为 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()
.
您可能需要考虑更改您的代码来执行类似的操作。但是,我不知道你想要实现的目标的完整背景,所以这个建议可能不相关。