在Objective-C中初始化一组结构

时间:2012-03-18 03:59:08

标签: objective-c arrays memory-management struct calloc

我已经读了一段时间了,我不确定我找到了一个好的答案。

我正在尝试设置一个包含92个结构的数组。它是一个固定长度,不会改变,因为它实际上是一个查找表。我认为最好的方法是先用calloc分配内存,然后加载数据。

但经过一些阅读后,我看到很多人在没有callocmalloc这样的情况下直接分配内存

 myStruct myData[92] = { {1,2}, {3,4}, ....};

我的第一个问题是动态分配内存是否更好?我的理解是这是一个更好的解决方案。特别是如果数据不一定会一直使用。

我的第二个问题是关于初始化数据。我已经读过我可以使用... = {....};初始化结构但编译器不接受它。

这是我到目前为止的代码:

typedef struct {
    int a;
    int b;
} myStruct;

@implementation MyClass

    static myStruct *myData;

    -(id) init {
         // ...

         myData = (myStruct *) calloc(92, sizeof(myStruct));
         myData[0] = {1,2}; // <=== Error ! Compiler says "Expected expression!"

         // ...

3 个答案:

答案 0 :(得分:5)

您的代码看起来像Objective-C,这是正确的吗?

如果您知道数组中有多少元素(并且它是一个理智的处理器和操作系统),则明确定义它总是更简单。

无论何时动态分配数组,都需要防止出现问题,这会使代码更难理解。

如果它确实是一个查找表,所有的值在编译时都是已知的,你可以初始化它:

struct {
    int a;
    int b;
} myStructDate[92] = { {1, 2}, {3, 4}, ... {181, 182}, {183, 184} };

答案 1 :(得分:3)

关于问题1:静态分配数组应该没问题。该数组将存储在二进制文件的数据部分中,将被加载到进程的虚拟内存中,并在必要时由操作系统转出,就像您的进程正在使用的任何其他内存一样。它还可以节省访问数据的时间,因为您不需要分配和初始化它。

关于问题2:gcc至少不喜欢像这样初始化数组元素。但你可以使用临时变量作弊:

myStruct s = {1,2};
myData[0] = s;

我不确定标准对此有何看法。

答案 2 :(得分:2)

因为这不是初始化,所以你需要做作业

myData[0].a = 1;
myData[0].b = 2;

初始化时可以使用{}初始化,就像这个例子一样,它也会设置你的数组。这有点浪费,因为如果使用上述方法,则不需要temp变量。

myStruct temp = {1,2};
myStruct* myData = (myStruct *) calloc(92, sizeof(myStruct));
myData[0] = temp;

关于何时在堆上分配内存(通过malloc / calloc)的一个好的经验法则是你需要在函数之外使用它。否则你应该在堆栈上做(使用局部变量)。