saurabh
saurabh

Reputation: 540

Memory leak in NSMutableArray

while(sqlite3_step(selectstmt) == SQLITE_ROW) {
            NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
//Expenseentry* temp=[[[Expenseentry alloc]init]autorelease];
//Expenseentry* temp=[[Expenseentry alloc]init];
            temp=nil;
            temp=[[Expenseentry alloc]init];
                        //memory leak here
            temp.ID=[NSString stringWithFormat:@"%d",primaryKey];
                        //memory leak here 
            int i=1;    
 @try{
//Expenseentry* temp=[[Expenseentry alloc]init];
//tried this but no luck
 NSString   *s=[[NSString alloc]initWithFormat:@"%f",sqlite3_column_double(selectstmt, 1)];
                        temp.amount=s;
                        [s release];
                        [arrreturn addObject:temp];
                        //[temp release];
//if i uncomment this app crashes 
                        //[formatter release];
                        //printf("\n daata count %d ",[arrreturn count]);
                    }
                    @catch(id ex )
                    {
                        printf("ooooopssss exception ");
                    }
                    i++;
            }


my expense entry class


@interface Expenseentry : NSObject {
    NSString *ID; 
    NSString *amount;

}
@property (nonatomic, retain) NSString *ID;
@property (nonatomic, retain) NSString *amount;
@end
 and .m is just 
- (void)dealloc {
    [ID release];
[amount release]
}

Upvotes: 1

Views: 256

Answers (3)

saurabh
saurabh

Reputation: 540

Ok I found my mistake just posting if any one can explain this behavior:
memory leak cause array and array-object were not released.If I would release any of it app crashes.

mistake 1:[super dealloc] missing in expenseentry's dealloc.
doubt:why is it required to release super? when apple doc says you have to release object you own.

mistake 2:array being returned by this function is stored in instance variable(and synthesized property with retain as attribute) of caller.
and I have released that property in dealloc as it is retained.

receivedArr=fun()

in dealloc

[receivedArr release]

Upvotes: 0

Joe
Joe

Reputation: 57169

  1. It looks like temp is an instance variable for that class
  2. Make sure you release temp when you are done or right before you use it again

Try doing the following

[temp release];
temp=[[Expenseentry alloc]init];
temp.ID=[NSString stringWithFormat:@"%d",primaryKey];

The other option is to release after your done with it inside of the while(sqlite3_step) loop

while(sqlite3_step(selectstmt) == SQLITE_ROW) {
...
temp=[[Expenseentry alloc]init];
temp.ID=[NSString stringWithFormat:@"%d",primaryKey];
... //Use temp
[temp release];
temp = nil; //Best practice to set it to nil

If the temp.ID string is leaking you need to look into the Expenseentry class to make sure your doing proper memory management there.

Edit: I now see the rest of your code posted

[arrreturn addObject:temp];
//[temp release];
//if i uncomment this app crashes

The reason why it is probably crashing is as I said before make sure you set it to nil after releasing

Edit 2: You are reusing the same object inside of the while loop also You will want to move the temp allocation into the while loop or else every object in that array will point to the same object. I am not sure what you goal is with the code but take at a look at the following code.

while(i>5)
{
   temp=[[Expenseentry alloc]init];
   temp.ID=[NSString stringWithFormat:@"%d",primaryKey];
   @try
   {
      NSString   *s=[[NSString alloc]initWithFormat:@"%f",sqlite3_column_double(selectstmt, 1)];
                        temp.amount=s;
                        [s release];
                        [arrreturn addObject:temp];
   }
   @catch(id ex )
   {
      printf("ooooopssss exception ");
   }
   [temp release];
   temp = nil;
   i++;
}

Upvotes: 2

AndersK
AndersK

Reputation: 36082

the temp=nil seems a bit odd. whenever you assign the variable temp to a new object don't forget to release the previous object.

if you write:

Expenseentry* temp=[[Expenseentry alloc]init];
temp=nil;

you get a memory leak because you have created an Expenseentry object and then said good riddance to the object basically. You need to do a [temp release]; before assigning to nil on the iphone.

there could be other leaks like in your Expenseentry but you don't show how it looks like i.e. how the properties ID are declared.

Upvotes: 1

Related Questions