如何在struct中使用动态C数组

时间:2013-03-20 22:03:55

标签: objective-c dynamic-memory-allocation

我在这里提出这个问题之前做了大量研究,但我找不到答案。

我有一个简单的结构,包含另一个结构的数组和总数:

typedef struct {
    int total;
    struct Struct1 arrayOfStructs[];
} Struct2;
Struct2 _myVar;  // the variable I need
  • arrayOfStructs[]应该是包含Struct1类型结构的C数组(此语法无效,因为您需要一个常量值)
  • totalarrayOfStructs
  • 的计数
  • Struct1不相关,它只包含一些原始数据)

问题是我希望这个数组是动态的。我希望能够做到这一点:

for (int i = 0; i < _myVar.total; i++) {
    NSLog(@"%d", _myVar.arrayOfStructs[i].index);
}

我尝试了以下内容:

typedef struct {
    int total;
    struct Struct1 *arrayOfStructs;  // USING A POINTER HERE
} Struct2;
Struct2 _myVar;  // the variable I need

并添加值:

int total = ++_myVar.total;  // increase total count
_myVar.arrayOfStructs = realloc(_myVar.arrayOfStructs, total * sizeof(Struct1));
_myVar.arrayOfStructs[total - 1] = {1, 5.3};  // appending a new value in the array

上面的代码正确地添加了值,但是在将它传递给NSData并检索它之后,数组项就丢失了,我最终得到了一些不好的指针:

[NSData dataWithBytes:&_myVar length:sizeof(_myVar) + sizeof(Struct1) * total];

我怀疑这是因为我需要sizeof(_myVar) + sizeof(Struct1) * total而不仅仅是sizeof(_myVar),所以由于指针地址不同,我最终会得到不良数据。我想我没有正确地将数据复制到我的结构中 任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:2)

您需要单独编写Struct1的内容:

myData = [NSMutableData dataWithBytes:&_myVar length:sizeof(_myVar)];
[myData appendBytes: _myVar.arrayOfStructs length: (_myVar.total * sizeof(Struct1)];

当你回读它时,你需要阅读它的第一部分,忽略你读取的arrayOfStructs的值,根据长度重新分配它,并将其余部分读入新分配的指针。

答案 1 :(得分:1)

_myVar是一个Struct2变量。所以它只有一个整数和一个指针。结构数组不属于_myVar。

因此,NSData的长度存在错误。在&amp; _myVar,只有一个大小为sizeof(struct2)的结构。

答案 2 :(得分:1)

在C中,通常在结构的末尾使用大小为1的数组。不知道它是否是Objective-C的标准。重新分配

(total- 1) * sizeof(Struct1) + sizeof(Struct2)

可能会有效。

我想。

编辑:

我的意思是,你可以这样做:

这将是你的结构:

typedef struct {
    int total;
    struct Struct1 arrayOfStructs[1];
} Struct2;
Struct2 *_myVar = malloc(sizeof(Struct2));

这是你添加元素的方式:

int total = ++_myVar->total;
realloc(_myVar, (total - 1) * sizeof(Struct1) + sizeof(Struct2));
_myVar->arrayOfStructs[total - 1] = {1, 5.3};

或类似的东西

答案 3 :(得分:0)

跟踪数组中的元素数量。要添加子项,请重新调用calloc,memcpy,并在数组中设置子项。

typedef struct Person {
    char *name;
    short age;
    struct Person *children;
    int numberOfChildren;
} Person;


#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
    @autoreleasepool {

        NSData *data;
        {
            // setup Carol
            Person ethan = { .name="Ethan", .age=14, .children=nil, .numberOfChildren=0 };
            Person terry = { .name="Terry", .age=16, .children=nil, .numberOfChildren=0 };
            Person carol = { .name="Carol", .age=40, .children=nil, .numberOfChildren=2 };
            carol.children=(Person  *)calloc(carol.numberOfChildren, sizeof(&carol));
            carol.children[0] = ethan;
            carol.children[1] = terry;

            // people
            Person  *people = (Person  *)calloc(1+carol.numberOfChildren, sizeof(*people));
            people[0] = carol;

            size_t bytesToCopy = 1+carol.numberOfChildren * sizeof(*people);
            data = [NSData dataWithBytes:people length:bytesToCopy];
        }

        {
            int elements = 1 + [data length]/sizeof(Person);
            Person  *people = (Person  *)calloc(elements, sizeof(*people));
            size_t bytesToCopy = [data length];
            const void *source = [data bytes];
            memcpy((void*)people, source, bytesToCopy); // memxxx are an ARC no-no

            for (int i = 0; i < 1; i=i+people[i].numberOfChildren) {
                printf("\nname=%s, age=%d, children=%d", people[i].name, people[i].age, people[i].numberOfChildren);
                for (int j = 0; j < people[i].numberOfChildren; j++) {
                     printf("\nname=%s, age=%d, children=%d", people[i].children[j].name, people[i].children[j].age, people[i].children[j].numberOfChildren);
                }
            }
        }

    }
}

打印

name=Carol, age=40, children=2
name=Ethan, age=14, children=0
name=Terry, age=16, children=0

考虑避免所有这些并切换到对象。