Objective-C EXEC_BAD_ACCESS when using flexible length arrays
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?
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
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 :)
精彩评论