0

ここでこの質問をする前に大規模な調査を行いましたが、答えが見つかりませんでした。

別の構造体の配列と合計を含む単純な構造体があります。

typedef struct {
    int total;
    struct Struct1 arrayOfStructs[];
} Struct2;
Struct2 _myVar;  // the variable I need
  • arrayOfStructs[]タイプの構造体を含む C 配列であるStruct1必要があります (定数値が必要なため、この構文は無効です)
  • totalのカウントですarrayOfStructs
  • 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

4 に答える 4

2

Struct1の内容を個別に記述する必要があります。

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

読み返すときは、最初の部分を読み取り、読み取ったarrayOfStructsの値を無視し、長さに基づいて再割り当てし、残りを新しく割り当てられたポインターに読み取る必要があります。

于 2013-03-20T22:23:31.853 に答える
1

_myVarはStruct2変数です。したがって、整数とポインタしかありません。構造体の配列は_myVarに属していません。

そのため、NSDataの長さにバグがあります。&_myVarには、サイズsizeof(Struct2)の構造体のみがあります。

于 2013-03-20T22:17:19.073 に答える
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};

またはそのようなもの

于 2013-03-20T22:21:49.080 に答える
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

これをすべて避けて、オブジェクトに切り替えることを検討してください。

于 2013-03-20T23:54:08.937 に答える