固定大小的结构数组的内存问题
Memory issues with fixed sized array of structs
我正在尝试创建一个小的固定大小的字符串列表,int 元组。固定大小的结构数组似乎是可行的方法,但是在操作数组条目时,我经常 运行 进入内存错误。到目前为止我尝试了什么:
public struct S {
public string a;
public int b;
public S (string a, int b) {
this.a = a;
this.b = b;
}
}
public class Test {
public S arr[5];
public static void main () {
var test = new Test ();
test.arr[0].a = "hi";
test.arr[0].b = 5;
/* alternatively: */
//test.arr[0] = S ("hi", 5);
}
}
我看过编译后的C代码,但我对C不是很熟悉。
我阅读了我发现的有关 vala 结构和结构数组的所有内容,但那里的一点点也没有启发我。
固定大小的数组似乎是用 "empty" 结构初始化的,我是否需要以某种方式对其进行初始化?
我对这里的结构数组有什么误解?
有没有另一种方法来实现固定大小的字符串列表,int 元组?结构数组不适合吗?
非常感谢任何帮助!这似乎是一项如此简单的任务,但我已经为此苦苦挣扎了好几天:/ ...
首先,您可以通过在 class 上指定 "Compact" 并禁用结构上的类型来简化 C 代码:
[CCode(has_type_id = false)]
public struct S {
public string a;
public int b;
public S (string a, int b) {
this.a = a;
this.b = b;
}
}
[Compact]
public class Test {
public S arr[5];
public static void main () {
var test = new Test ();
test.arr[0].a = "hi";
test.arr[0].b = 5;
/* alternatively: */
//test.arr[0] = S ("hi", 5);
}
}
不是完整的答案,但编译器生成的破坏代码似乎有问题:
void test_free (Test* self) {
_vala_array_destroy (self->arr, 5, (GDestroyNotify) s_destroy);
g_slice_free (Test, self);
}
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
if ((array != NULL) && (destroy_func != NULL)) {
int i;
for (i = 0; i < array_length; i = i + 1) {
if (((gpointer*) array)[i] != NULL) {
destroy_func (((gpointer*) array)[i]);
}
}
}
}
请注意 array
参数(属于 gpointer
类型,但从 S[]
转换而来,即 arr)如何在destroy_func ()
被调用。
如果 arr
是一个动态数组就好了,但它不是。
如果我手动修改编译器输出,一切正常:
static void _vala_array_destroy (S* array, gint array_length, GDestroyNotify destroy_func) {
if ((array != NULL) && (destroy_func != NULL)) {
int i;
for (i = 0; i < array_length; i = i + 1) {
if (&array[i] != NULL) {
destroy_func (&array[i]);
}
}
}
}
销毁函数(destroy_func
又名 s_destroy
)现在在有效的 S*
(数组中结构的地址)上调用。
所以在我看来,您发现了一个编译器错误。
PS:使用动态数组效果很好,我要么这样做,要么使用一些更高级别的数据类型,如 Gee.ArrayList
而不是静态数组。
我正在尝试创建一个小的固定大小的字符串列表,int 元组。固定大小的结构数组似乎是可行的方法,但是在操作数组条目时,我经常 运行 进入内存错误。到目前为止我尝试了什么:
public struct S {
public string a;
public int b;
public S (string a, int b) {
this.a = a;
this.b = b;
}
}
public class Test {
public S arr[5];
public static void main () {
var test = new Test ();
test.arr[0].a = "hi";
test.arr[0].b = 5;
/* alternatively: */
//test.arr[0] = S ("hi", 5);
}
}
我看过编译后的C代码,但我对C不是很熟悉。 我阅读了我发现的有关 vala 结构和结构数组的所有内容,但那里的一点点也没有启发我。
固定大小的数组似乎是用 "empty" 结构初始化的,我是否需要以某种方式对其进行初始化? 我对这里的结构数组有什么误解? 有没有另一种方法来实现固定大小的字符串列表,int 元组?结构数组不适合吗?
非常感谢任何帮助!这似乎是一项如此简单的任务,但我已经为此苦苦挣扎了好几天:/ ...
首先,您可以通过在 class 上指定 "Compact" 并禁用结构上的类型来简化 C 代码:
[CCode(has_type_id = false)]
public struct S {
public string a;
public int b;
public S (string a, int b) {
this.a = a;
this.b = b;
}
}
[Compact]
public class Test {
public S arr[5];
public static void main () {
var test = new Test ();
test.arr[0].a = "hi";
test.arr[0].b = 5;
/* alternatively: */
//test.arr[0] = S ("hi", 5);
}
}
不是完整的答案,但编译器生成的破坏代码似乎有问题:
void test_free (Test* self) {
_vala_array_destroy (self->arr, 5, (GDestroyNotify) s_destroy);
g_slice_free (Test, self);
}
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
if ((array != NULL) && (destroy_func != NULL)) {
int i;
for (i = 0; i < array_length; i = i + 1) {
if (((gpointer*) array)[i] != NULL) {
destroy_func (((gpointer*) array)[i]);
}
}
}
}
请注意 array
参数(属于 gpointer
类型,但从 S[]
转换而来,即 arr)如何在destroy_func ()
被调用。
如果 arr
是一个动态数组就好了,但它不是。
如果我手动修改编译器输出,一切正常:
static void _vala_array_destroy (S* array, gint array_length, GDestroyNotify destroy_func) {
if ((array != NULL) && (destroy_func != NULL)) {
int i;
for (i = 0; i < array_length; i = i + 1) {
if (&array[i] != NULL) {
destroy_func (&array[i]);
}
}
}
}
销毁函数(destroy_func
又名 s_destroy
)现在在有效的 S*
(数组中结构的地址)上调用。
所以在我看来,您发现了一个编译器错误。
PS:使用动态数组效果很好,我要么这样做,要么使用一些更高级别的数据类型,如 Gee.ArrayList
而不是静态数组。