Problem Deleting From NSMutableArray

Discussion in 'Mac Programming' started by stadidas, Jan 16, 2007.

  1. macrumors regular

    Joined:
    Feb 27, 2006
    Location:
    Kent, United Kingdom
    #1
    Hi everyone.

    I'm currently having a big problem with an NSMutableArray. At the moment I can addobjects to it, and they display in a NSTableView perfectly. When I remove them they are removed from the array, but when I try to open the sheet containing the tableView I get an error like this: *** -[NSCFArray objectAtIndex:]: index (1) beyond bounds (1)

    If I then add another object to the array, the tableView works perfectly again. If I do not add another object and quit, I get this sort of error:
    AssetMonitor [DEBUG](3206,0xa000ed88) malloc: *** Deallocation of a pointer not malloced: 0xbfffe270; This could be a double free(), or free() called with the middle of an allocated block; Try setting environment variable MallocHelp to see tools to help debug

    These are the methods I have for adding and removing:
    Code:
    - (void)addLog:(Log *)l
    {
    	[logs addObject:l];
    }
    
    - (void)removeObjectIdenticalTo:(id)anObject
    {
    	[logs removeObjectIdenticalTo:anObject];
    }
    
    I've been playing around for a few hours and haven't been able to come up with a fix. Any help appreciated with this one. Thanks.
     
  2. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #2
    Please post more code. Sounds like you're not using memory management correctly. And remember arrays start with an index of 0 for their first item.
     
  3. thread starter macrumors regular

    Joined:
    Feb 27, 2006
    Location:
    Kent, United Kingdom
    #3
    I suspect it's memory management too.
    Here are the methods from MyDocument:
    Code:
    - (void)add:(double)d:(NSString *)s
    {
    	Log *l = [[Log alloc] init];
    	[l setDescription:s];
    	[l setAmount:d];
    	[self doAdd:d:s:l];
    }
    
    - (void)doAdd:(double)d:(NSString *)s:(Log *)l
    {
    	[self addAmount:d];
    	[self addLog:l];
    	[tableView reloadData];
    	
    	NSUndoManager *undo = [self undoManager];
    	[[undo prepareWithInvocationTarget:self]
    		removeLog:l];
    	
    	[[undo prepareWithInvocationTarget:self]
    		subtractAmount:d];
    	
    	if (![undo isUndoing]) {
    		[undo setActionName:@"Add to Balance"];
    	}
    }
    
    - (void)addAmount:(double)d
    {
    	double tempBalance = [myBalance doubleValue];
    	double newBalance = tempBalance + d;
    	[detailsController setMyBalance:newBalance];
    }
    
    - (void)addLog:(Log *)l
    {
    	[detailsController addLog:l];
    }
    
    - (void)removeLog:(id)anObject
    {
    	[detailsController removeObjectIdenticalTo:anObject];
    }
    
    - (void)subtract:(double)d:(NSString *)s
    {
    	Log *l = [[Log alloc] init];
    	[l setDescription:s];
    	[l setAmount:d];
    	[self doSubtract:d:s:l];
    }
    
    - (void)doSubtract:(double)d:(NSString *)s:(Log *)l
    {
    	[self subtractAmount:d];
    	[self addLog:l];
    	[tableView reloadData];
    	
    	NSUndoManager *undo = [self undoManager];
    	[[undo prepareWithInvocationTarget:self]
    		removeLog:l];
    	
    	[[undo prepareWithInvocationTarget:self]
    		addAmount:d];
    	
    	if (![undo isUndoing]) {
    		[undo setActionName:@"Subtract From Balance"];
    	}
    	
    }
    
    - (void)subtractAmount:(double)d
    {
    	double tempBalance = [myBalance doubleValue];
    	double newBalance = tempBalance - d;
    	[detailsController setMyBalance:newBalance];
    }
    
    The add: and subtract: methods are called from when a sheet is closed which passes the values. detailsController refers to an instance of a class called details which stores the NSMutableArray. The problem I described in the first post came from calling the add: method, and then hitting undo, which I expected to remove the instance of Log that had been stored.
    Let me know if you want to see anything else.
     
  4. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #4
    Well when you make your Log objects, you're leaking memory:

    Code:
    Log *l = [[Log alloc] init];
    [l setDescription:s];
    [l setAmount:d];
    [self doAdd:d:s:l];
    Should be

    Code:
    Log *l = [[Log alloc] init];
    [l setDescription:s];
    [l setAmount:d];
    [self doAdd:d:s:l];
    [l release];
    (unless you were on 10.5 with GC enabled ;)
     
  5. macrumors 68040

    mduser63

    Joined:
    Nov 9, 2004
    Location:
    Salt Lake City, UT
    #5
    I might point out that it's horrible programming style to use single character names for variables/arguments. Makes for really difficult reading later.

    Note: If you're trying to make your code hard to read for some reason, ignore this.
     

Share This Page