2017-10-28 53 views
0

我正在尝试创建一个小的固定大小的字符串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

首先,你可以通过特定的“压缩”类来使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()。如果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而不是静态数组。