我正在尝试创建一个小的固定大小的字符串列表,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结构和结构数组的所有内容,但是那里的一点点也没有启发我。
固定大小的数组似乎用“空”结构进行初始化,我是否需要在某种程度上初始化它? 我对这里的结构数组有什么误解? 是否有另一种方法来实现固定大小的字符串,int元组列表?结构阵列是否不适合它?
非常感谢任何帮助!这似乎是一项如此简单的任务,但我现在已经挣扎了好几天了:/ ...
答案 0 :(得分:0)
首先,您可以通过特定的" 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)如何在{gpointer*
之前投放到destroy_func ()
在其上调用1}}。
如果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
(数组中的struct的地址)上调用destroy函数(s_destroy
aka S*
)。
所以在我看来你发现了一个编译器错误。
PS:使用动态数组工作正常,我会这样做或使用更高级别的数据类型,如Gee.ArrayList
而不是静态数组。