Objective-C EXEC_BAD_ACCESS when using flexible length arrays

301 Views Asked by At

I have done some testing on some behavior I have found, and I was wondering if someone can help me understand what is going on.

I have a struct, called myStruct, that looks like this:

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

And I run this code on it:

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;
}

It works fine. However, when I change the struct declaration to this:

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

I get EXEC_BAD_ACCESS when I call the line [a release].

Can anyone help me understand what is going on here?

2

There are 2 best solutions below

3
On BEST ANSWER

You have to actually allocate space for your flexible array member! This line:

myStruct my;

Only makes enough stack space for size (or myVar and size from your second example). It appears that in your failing case you're overwriting a on the stack, but really both cases are wrong. To fix your problem, you need to allocate space for the floats[] member of the structure:

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

Don't forget to free() it when you're done!

A quick example - this program:

#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;
}

and its output:

$ make testapp
cc     testapp.c   -o testapp
$ ./testapp 
8
3
On

You're not allocating any memory for your floats - I'm surprised it's not crashing sooner!

Do you need to malloc some memory for the floats[] pointer?


After a quick test I get EXC_BAD_ACCESS for both definitions of myStruct :)