Understanding "release"

Joined
Jul 18, 2010
Messages
1
Reaction score
0
Points
1
I've bolded the part of the code I don't fully understand.

  • Won't sum = sum2 just overwrite the old sum? So why do you need to release it beforehand?
  • Why isn't sum2 released at the end of the program? Should it be?

Code:
#import “Fraction.h”

int main (int argc, char *argv[])
{

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Fraction *aFraction = [[Fraction alloc] init]; Fraction *sum = [[Fraction alloc] init], *sum2; int i, n, pow2;

[sum setTo: 0 over: 1]; // set 1st fraction to 0

NSLog (@”Enter your value for n:”);
scanf (“%i”, &n);
pow2 = 2;

for (i = 1; i <= n; ++i) {
     [aFraction setTo: 1 over: pow2];
     sum2 = [sum add: aFraction];
 [B]    [sum release]; // release previous sum
     sum = sum2;[/B]
     pow2 *= 2;
}

NSLog (@”After %i iterations, the sum is %g”, n, [sum convertToNum]); [aFraction release];
[sum release];
[pool drain];

return 0;
}
 
Joined
Feb 25, 2009
Messages
2,112
Reaction score
71
Points
48
Your Mac's Specs
Late 2013 rMBP, i7, 750m gpu, OSX versions 10.9.3, 10.10
You need to be aware of your memory management - especially if you're learning to ultimately program apps for an iPhone/iPod/iPad.

ANY time you alloc memory, unless you specifically move it into the autorelease pool (or you're on a device and are using garbage collection), you need to release it yourself.

Let's say in that case, your n was set at 100,000 (God only knows why you'd want to go that high), and you didn't release - you'd have 100,000 objects in memory that you've now lost control of because you assigned sum2 to sum without releasing sum first. Now imagine that each of those items took 1000 bytes, you've used up 100,000,000 bytes of memory (give or take) and if you were on an iPhone, you'd be getting a warning that memory is getting low and you have NO way to release it since it's not in an autorelease pool you can drain.

All sum is is a pointer to a block of memory.

When you type:

sum = sum2

you've now set sum to point to the block of memory that sum2 is pointing at. Once you've done that you no longer have a reference to the block of memory that sum was pointing at. Since you don't have that reference you can't release that memory.

It may seem like a minor thing, but it can add up - especially if you have a lot of large blocks of memory, or are on an iPhone where there is no garbage collection and you've very limited memory to work with compared to a full Mac.

sum2 isn't released at the end because just before falling out of the for loop, sum has been set to sum2 (not the value that sum2 holds, it's now pointing to the same block of memory as sum2) so you only need to release one of the two objects. You could have released either sum or sum2, but not both. Once you've released sum there should be a 0 retain count and you don't need to release again.

There is a caveat - and I only know that it's working this way because I know you're reading Programming in Objective-C 2.0 - NORMALLY, a method that is called like what you have:

sum2 = [sum add: aFraction];

you would be returned an autoreleased object. But, you haven't gotten to the portion of the book that discusses autorelease. At this point - if I'm remembering my chapters right, in that add: method, it's alloc'ing memory but not assigning it to the autorelease pool.
 
Joined
Jun 25, 2005
Messages
3,231
Reaction score
112
Points
63
Location
On the road
Your Mac's Specs
2011 MBP, i7, 16GB RAM, MBP 2.16Ghz Core Duo, 2GB ram, Dual 867Mhz MDD, 1.75GB ram, ATI 9800 Pro vid
You haven't supplied enough code for anyone to have a good response. You'll need to also supply the Fraction source. For instance, what is returned from the add: method? We don't know if it is a fraction type, or a object pointer, or something else.

I would expect this code to crash if n is greater than 1 because of the release.

EDIT: I see Nethfel knows the source of the material and was able to give a better response.
 
Joined
Feb 25, 2009
Messages
2,112
Reaction score
71
Points
48
Your Mac's Specs
Late 2013 rMBP, i7, 750m gpu, OSX versions 10.9.3, 10.10
Yeah, the only reason I knew is because I read the book recently and I recognized the code :)

If he's using the code I'm pretty sure he's using - the add: method AT THIS POINT in the book (around chapter 7) is:

Code:
-(Fraction *) add: (Fraction *) f
{
  Fraction *result = [[Fraction alloc] init];
  int resultNum, resultDenom;

  resultNum = numerator * f.denominator + denominator * f.numerator;
  resultDenom = denominator * f.denominator;
 
  [result setTo: resultNum over: resultDenom];
  [result reduce];

  return result;
}

Later in the book when he gets into memory management - at that point your instructed on how to correct the code to return an autorelease object rather then an object that needs to be released by calling code.
 

Shop Amazon


Shop for your Apple, Mac, iPhone and other computer products on Amazon.
We are a participant in the Amazon Services LLC Associates Program, an affiliate program designed to provide a means for us to earn fees by linking to Amazon and affiliated sites.
Top