1

私が見つけたいくつかの動作についていくつかのテストを行いました.誰かが何が起こっているのかを理解するのを手伝ってくれるかどうか疑問に思っていました.

myStruct次のようなと呼ばれる構造体があります。

typedef struct {
    int size;
    float floats[];
} myStruct;

そして、このコードを実行します:

int main () {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSArray *a = [[NSArray alloc] initWithObjects:@"0.2", @"0.5", @"0.5", nil];

    NSLog(@"%@", a);

    myStruct my;
    my.size = a.count;

    my.floats[0] = [[a objectAtIndex:0] floatValue];
    my.floats[1] = [[a objectAtIndex:1] floatValue];
    my.floats[2] = [[a objectAtIndex:2] floatValue];

    NSLog(@"{ %lf, %lf, %lf }", my.floats[0], my.floats[1], my.floats[2]);

    [a release];    
    [pool drain];
    return 0;
}

それは正常に動作します。ただし、構造体宣言を次のように変更すると:

typedef struct {
    float myVar;
    int size;
    float floats[];
} myStruct;

回線を呼び出すと、EXEC_BAD_ACCESS が返されます[a release]

ここで何が起こっているのかを理解してくれる人はいますか?

4

2 に答える 2

4

柔軟な配列メンバーに実際にスペースを割り当てる必要があります! この行:

myStruct my;

size(または2番目の例から)myVarに十分なスタックスペースのみを作成します。size失敗した場合a、スタックを上書きしているように見えますが、実際には両方のケースが間違っています。floats[]問題を解決するには、構造体のメンバーにスペースを割り当てる必要があります。

myStruct *my = malloc(sizeof(myStruct) + a.count * sizeof(float));

free()終わったら忘れずに!

簡単な例 - このプログラム:

#include <stdio.h>

typedef struct {
    float myVar;
    int size;
    float floats[];
} myStruct;

int main(int argc, char **argv)
{
  printf("%zu\n", sizeof(myStruct));
  return 0;
}

およびその出力:

$ make testapp
cc     testapp.c   -o testapp
$ ./testapp 
8
于 2011-02-15T17:38:57.863 に答える
2

フロートにメモリを割り当てていません-すぐにクラッシュしないことに驚いています!

floats[] ポインター用にメモリを malloc する必要がありますか?


簡単なテストの後、myStruct の両方の定義に対して EXC_BAD_ACCESS を取得します:)

于 2011-02-15T17:37:37.553 に答える