【问题标题】:Initialising an array of structs in Objective-C在 Objective-C 中初始化结构数组
【发布时间】:2012-03-18 03:59:07
【问题描述】:

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

我正在尝试设置一个包含 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!"

         // ...

【问题讨论】:

  • myData[0]=... 是一个赋值,而不是初始化。不幸的是,初始化语法不允许赋值。
  • 既然可以进行静态分配,为什么还要使用动态分配? static myStruct myData[92]
  • 这是我想要理解的事情之一。我认为最好对未知事物进行动态处理,而静态是固定的。所以我最初的动态代码应该是静态的,即使它(相对而言)很大?

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


【解决方案1】:

你的代码看起来像 Objective-C,对吗?

如果您知道数组中有多少元素(并且它是一个健全的处理器和操作系统),那么显式定义它总是更简单。

每当您动态分配一个数组时,您都需要防止出现问题,从而使代码更难理解。

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

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

【讨论】:

  • 并且,如果值是常量,则标记整个数组const,它可能会被添加到程序的只读“文本”部分。
【解决方案2】:

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

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

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

我不太确定标准对此有何规定。

【讨论】:

    【解决方案3】:

    因为这不是初始化,你需要做赋值

    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)的一个很好的经验法则是,如果您需要在函数之外使用它。否则,您可能应该在堆栈上执行此操作(使用局部变量)。

    【讨论】:

      猜你喜欢
      • 2010-09-23
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多