Reputation: 5616
I have the following method in my app :
- (void) loadModel {
// Runs in a seperate thread so we need to create an additional NSAutoreleasePool
pool = [[NSAutoreleasePool alloc] init];
NSData *getData = [activeModelInfo getFileData];
if (getData) {
if ([activeModel loadFromFileData:daeData]) {
[activeModel reset];
[mainViewController performSelectorOnMainThread:@selector(showModelView) withObject:nil waitUntilDone:NO];
}
else {
}
}
else {
}
[pool release];
}
The loadFromFileData method calls the following code which loads data. :
- (void) loadVerticesFromSource:(NSString*)verticesSourceId meshNode:(TBXMLElement*)meshNode intoMesh: (Mesh3D*) mesh {
NSLog(@"Getting Vertices for Source %@",verticesSourceId);
FloatArray *floatArray = [self getFloatArrayFromSource: verticesSourceId meshNode: meshNode];
if (floatArray) {
[daeFloatArray addObject:floatArray];
}
if (floatArray) {
if ([floatArray.array count] % 3 != 0) {
NSLog(@"Float array length not divisible by 3!");
}
else {
mesh->verticesCount = [floatArray.array count] / 3;
mesh->vertices = malloc(sizeof(Vector3D) * mesh->verticesCount);
for (int i=0; i<mesh->verticesCount; i++) {
mesh->vertices[i].x = [[floatArray.array objectAtIndex:(i*3)] floatValue];
mesh->vertices[i].y = [[floatArray.array objectAtIndex:(i*3)+1] floatValue];
mesh->vertices[i].z = [[floatArray.array objectAtIndex:(i*3)+2] floatValue];
// update extents information
if (!extents.pointDefined || mesh->vertices[i].x < extents.minX) extents.minX = mesh->vertices[i].x;
else if (!extents.pointDefined || mesh->vertices[i].x > extents.maxX) extents.maxX = mesh->vertices[i].x;
if (!extents.pointDefined || mesh->vertices[i].y < extents.minY) extents.minY = mesh->vertices[i].y;
else if (!extents.pointDefined || mesh->vertices[i].y > extents.maxY) extents.maxY = mesh->vertices[i].y;
if (!extents.pointDefined || mesh->vertices[i].z < extents.minZ) extents.minZ = mesh->vertices[i].z;
else if (!extents.pointDefined || mesh->vertices[i].z > extents.maxZ) extents.maxZ = mesh->vertices[i].z;
if (!extents.pointDefined) extents.pointDefined = YES;
[pointerStorageArray addObject:[NSValue valueWithPointer:mesh->vertices]];
}
}
}
}
Since this method is called several times while the data loads, each time mallocing memory for the mesh->vertices struct, I have created a pointerStorage array where I store the pointer to the malloced memory.
The app then displays a 3D object using OpenGL ES. When the user presses a Main Menu button, I then free up the pointerStorageArray as follows :
- (void) freeUpMallocedMemory
for (NSValue * value in pointerStorageArray) {
free(value);
}
The problem is that the app then crashes during this process. All I get is the EXC_BAD_ACCESSS error message and a pointer to the following line of code in the loadModel method above :
[pool release];
Nothing in the stack trace. I have also tried turning on NSZombie, NSAutoreleaseTrackFreedObjectCheck and NSDebugEnabled, but I still don't get any additional information.
The odd thing is that if I put a delay on the button of 2 seconds (i.e only trigger the freeUpMallocedMemory method after 2 seconds), the app no longer crashes and works fine.
Can anyone suggest what might be causing this - really confused and have already spent a few days troubleshooting.
Thank you !
Upvotes: 1
Views: 605
Reputation: 22334
You are over-releasing... the values in pointerStorageArray are created via a convenience method and as such don't need releasing, simply removing them from the array will dispose of them.
Upvotes: 3