Objective-C EXEC_BAD_ACCESS при использовании массивов гибкой длины - PullRequest
1 голос
/ 15 февраля 2011

Я провел некоторое тестирование на обнаруженном мной поведении, и мне было интересно, если кто-нибудь может помочь мне понять, что происходит.

У меня есть структура, которая называется 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].

Может кто-нибудь помочь мне понять, что здесь происходит?

Ответы [ 2 ]

4 голосов
/ 15 февраля 2011

Вы должны фактически выделить место для вашего гибкого члена массива!Эта строка:

myStruct my;

Занимает только место в стеке для size (или 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
2 голосов
/ 15 февраля 2011

Вы не выделяете память для своих поплавков - я удивлен, что это не даст сбой раньше!

Нужно ли выделять память для указателя с плавающей точкой []?


После быстрого теста я получаю EXC_BAD_ACCESS для обоих определений myStruct:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...