PDA

View Full Version : NSArray becomming invalid second time execute is called, custom patch




SW::Lango
Mar 18, 2008, 05:02 AM
Hey

i have a NSArray * variable (called _heightMap) in my custom patch class. In init: i create it...


-(NSArray *)generateHeightMap:(double)maxHeight
minHeight:(double)minHeight
numPoints:(int)numPoints
{
// Create mutable array to hold the points
NSMutableArray *heightMap;
heightMap = [NSMutableArray arrayWithCapacity:numPoints];

// cycle through each point
NSInteger i;
for (i=0; i<numPoints; i++) {
NSNumber *nextHeight;
nextHeight = [NSNumber numberWithDouble:rand()%100/100.0*maxHeight + minHeight];
[heightMap insertObject:nextHeight atIndex:0];
}

return (NSArray *)heightMap;
}


- (id) init
{
NSLog(@"init:");
if(self = [super init]) {
// Set random seed
[[NSDate date] timeIntervalSince1970];
_heightMap = [self generateHeightMap:DEFAULTINPUTMAXHEIGHT
minHeight:DEFAULTINPUTMINHEIGHT
numPoints:DEFAULTINPUTNUMPOINTS];
}

return self;
}

The first time execute: is called

- (BOOL) execute:(id<QCPlugInContext>)context atTime:(NSTimeInterval)time withArguments:(NSDictionary*)arguments
{
NSLog([_heightMap description]);
return YES;
}


It traces the _heightMap value. But the second time the program freezes and debug comes up. If i 'continue' i get a bad access or something similar error.

I'm assuming that something happens to my _heightMap to cause any reads from it throw an error, perhaps its been freed. This must happen after the execute: but i have no idea by what, or when.

Has anyone had any other problems like this?

I notice in simpleLandGenerator: i return a pointer of the mutable array typecasted as an NSArray, the mutable array is a subclass of NSArray so there shouldn't be any dramas here should there?

Any help would be super



SW::Lango
Mar 18, 2008, 05:45 AM
g'day all

i seemed to of figure out what the problem was. In short it was these lines in generateHeightMap:


...
NSMutableArray *heightMap;
heightMap = [NSMutableArray arrayWithCapacity:numPoints];
...
[heightMap insertObject:nextHeight atIndex:0];


This must be the wrong way to do it. From what i believe, it seems to 'push' the objects in at position 0, causing the others to go backwards, and thus some go out of bounds. Although in my code the objects going out of bounds where not any values i had given it must of had an affect that caused the error the second time execute: was called

If i use

...
NSMutableArray *heightMap;
heightMap = [[NSMutableArray alloc] init];
...
[heightMap addObject:nextHeight];


Then no erros occur. Most likely because no objects are going out of bounds.

I have a rough understanding of what is going wrong in my original code, but i am not 100% certain. Does anyone have any ideas or theories on why the error was occuring?

Cheers

Lango

robbieduncan
Mar 18, 2008, 06:03 AM
arrayWithCapacity: is a convenience method that creates AND autoreleases the array it returns. As it's autoreleased it will be deleted next time through the runloop.

There is a convention in Cocoa: objects returned by alloc/init and copy methods are not autoreleased, all others are.

SW::Lango
Mar 22, 2008, 11:19 PM
Thanks for that

I've read a few documents now about memory management and it makes sense to me.

Thanks again for your help.

Cheers

David