Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan

Old Stuff => Chapter 7 - More on Classes => : amuso February 12, 2009, 06:21:31 AM



: Program 7.5 - 7.6 stuck
: amuso February 12, 2009, 06:21:31 AM
This kind of is the reason I am stuck at 7.6 in another thread (errata), so I figured I would go back to the root of my confusion...

In program 7.5 on page 151 you declare a fraction *resultFraction without alloc and init it... And later in the text you ask why it doesnt have to be allocated and initialized. And I have no clue :)

This continues in 7.6 where I still dont get why sum2 isnt alloc/init either, and why it isnt released after use.

Its official. I have lost the thread  :D



: Re: Program 7.5 - 7.6 stuck
: skochan February 12, 2009, 07:11:55 AM
The declaration
: (Objective-C)
Fraction *resultFraction;

does not allocate space for a Fraction object, as you are aware.  


It allocates space for a variable called resultFraction that you can conceptualize like this:

: (Objective-C)
    
       resultFraction                                                
     ---------------------            
     |                    |
     ---------------------              

A subsequent statement like
: (Objective-C)
resultFraction = [[Fraction alloc] init];
will set up the connection between an allocated Fraction object and resultFraction like this:
: (Objective-C)
        resultFraction              Fraction Object
        ---------------------     -------------------------
        |         o----------|--->|                       |  numerator
        ---------------------     -------------------------
                                  |                       |  denominator
                                  ------------------------
(This concept is also described later in the book starting on page 172)

So resultFraction doesn't actually contain the numerator and denominator of a Fraction, but it references a place in memory that does.    In the case of Program 7.5, the add: method allocates the actual Fraction object (called result inside the method) and returns a reference (pointer) to it that gets stored inside resultFraction by the program when the statement

: (Objective-C)
resultFraction = [aFraction add: bFraction];

gets executed.  This creates the relationship depicted in the diagram above.  

In Program 7.6, you end up with both sum and sum2 referencing (pointing to) the same Fraction object in memory.  And you can only release that object's memory once.

I hope this helps.  If not, let me know and I'll try again (although it's a royal pain trying to draw those rectangles with dashes and vertical bars!!)   ;D

Cheers,

Steve


: Re: Program 7.5 - 7.6 stuck
: amuso February 12, 2009, 07:43:42 AM
Thanks so much for answering all these silly questions. I am sure you have gotten them a zillion times before and probably start to get tired of them :)

Actually that DOES make it comphrensive! And it makes it quite logical why you wouldnt release the sum2 since its just a pointer.

Ok, I think I got it :) Time for the next chapter. Well, actually I have to do my exercises first.


: Re: Program 7.5 - 7.6 stuck
: skochan February 12, 2009, 07:52:19 AM
No, I don't get tired.   It's rewarding for me if I can help someone to learn something new.  :)

Cheers,

Steve


: Why is sum2 needed?
: InRainbows February 20, 2009, 07:38:46 PM
I don't understand why you need to create sum2 in the first place. It seems to me like you could just have sum and then change the for loop to:

: (Objective-C)
for (i = 1; i <= n; ++i) {
    [aFraction setTo: 1 over: pow2];
    sum = [sum add: aFraction];
    pow2 *= 2;
}

I would think that you wouldn't be creating more references in memory by doing this, so later when you finally type [sum release] it releases the one and only number stored in memory. I must not be correctly understanding this memory management. Any help? Thank you!


: Re: Program 7.5 - 7.6 stuck
: esc February 20, 2009, 10:16:50 PM
I don't understand why you need to create sum2 in the first place. It seems to me like you could just have sum and then change the for loop to:

: (Objective-C)
for (i = 1; i <= n; ++i) {
    [aFraction setTo: 1 over: pow2];
    sum = [sum add: aFraction];
    pow2 *= 2;
}

I would think that you wouldn't be creating more references in memory by doing this, so later when you finally type [sum release] it releases the one and only number stored in memory. I must not be correctly understanding this memory management. Any help? Thank you!

Hi there,

Please note that the add: method used in program 7.6 returns the allocated memory for the result (see the add: method at the bottom of page 150).  If you don't use the variables sum and sum2 like in program 7.6 to release the memory created by add:, then each time you go through the for loop, your program will leak memory.  There's an explanation on page 153 (first two paragraphs) for the effect you create by your code above (cutting out the sum2 variable).



: Re: Why is sum2 needed?
: mdeh February 20, 2009, 11:44:23 PM
I don't understand why you need to create sum2 in the first place. It seems to me like you could just have sum and then change the for loop to:

: (Objective-C)
for (i = 1; i <= n; ++i) {
    [aFraction setTo: 1 over: pow2];
    sum = [sum add: aFraction];
    pow2 *= 2;
}

I would think that you wouldn't be creating more references in memory by doing this, so later when you finally type [sum release] it releases the one and only number stored in memory. I must not be correctly understanding this memory management. Any help? Thank you!


It took me a while to figure this out too.
You are assuming that the *sum* outside of the "[" and the *sum* inside the "[" occupy the same space in memory. Remember, all that sum is, is a variable pointing to a bit of memory. So the sum of [sum add:....] points to here; (Lets just call it A). 


      A              B
|------------|--------------|


Now, when you get the return from your method, you are changing where it is pointing. Why? Because a **new** object ( lets say B ) was created in another part of your program (which it was) , and that reference was handed back to you, so now SUM is **assigned** that ref, which is B ( as we have arbitrarily decided). But, what about A? Under the rules with which you have designed your program, you agree to manage memory. Just because sum is no longer pointing at A, does not mean the system knows that it is free ( or cares ), and it will be unavailable to anything else....that's what leaking memory is. So, it is up to you to release A before you assign it to B. So, it is **not** that you cannot do it your way. It is that it will be doing something which is undesirable.
Hope that helps.


: Re: Program 7.5 - 7.6 stuck
: InRainbows February 27, 2009, 07:04:18 PM
Thanks a lot. I think I understand it now. I didn't realize that sum was a pointer and that another object was being created whenever the add method was being called. Thanks again!


: Re: Program 7.5 - 7.6 stuck
: ezrock March 20, 2009, 12:59:25 PM
I am confused as well. When the topic of memory leakage is described on p.153, the prescribed method of correctly handling leakage "is to divide the messages into two separate messages, as was done earlier in the program." S. Kochan is referring to these lines on p. 152 (I believe):

: (Objective-C)
resultFraction = [aFraction add: bFraction]; 
[resultFraction print];
...
[resultFraction release];

Here, as I understand it, the add method creates a new Fraction that doesn't get released in the add: method. By assigning that object to a variable name, it can be released later as is done with "[resultFraction release];" That is contrasted with [[aFraction add: bFraction ] print]; in which that new Fraction is created with the add: method but, since unnamed, not release-able.

So if I get that correctly, what is going with Program 7.6 ? sum is declared and allocated, sum2 is simply declared. Then, in the for loop, sum2 is assigned the return value of [sum add: aFraction], which as I understand it, creates an unnamed Fraction object that can't be released. Then sum2 is given the value of sum, which was just released. That is the most confusing part for me, because I would think that if sum was released, it doesn't exist for it to be assigned to sum2.

Like I said, I'm confused.


: Re: Program 7.5 - 7.6 stuck
: skochan March 20, 2009, 01:11:10 PM
So if I get that correctly, what is going with Program 7.6 ? sum is declared and allocated, sum2 is simply declared. Then, in the for loop, sum2 is assigned the return value of [sum add: aFraction], which as I understand it, creates an unnamed Fraction object that can't be released. Then sum2 is given the value of sum, which was just released. That is the most confusing part for me, because I would think that if sum was released, it doesn't exist for it to be assigned to sum2.

Okay, so I think you understand the concept but you're not reading the code correctly.  sum gets released and then sum is given the value of sum2, not the other way around as you stated.  Reread the code and you'll see that's what is taking place.

Cheers,


Steve Kochan


: Re: Program 7.5 - 7.6 stuck
: ezrock March 20, 2009, 01:16:24 PM
I actually re-read a bunch of times, and drew out on paper what was happening at each stage, and it became clear. I recommend that technique to anyone that is getting stuck here.

Thank you very much for your help, by the way.
It's very helpful to know that you are on the forums.


: Re: Program 7.5 - 7.6 stuck
: demetri007 March 20, 2009, 07:31:02 PM
: (Objective-C)
for (i = 1; i <= n; ++i) {
     [aFraction setTo: 1 over: pow2];
     sum2 = [sum add: aFraction];
     [sum release];    // release previous sum
     sum = sum2;
     pow2 *= 2;
}

Am I correct in stating that sum2's value is a memory address of an Fraction object created & returned when sum's add: method was called?

Also:
sum2 received the result Fraction from sum's add: call
Then sum was released
Then sum was given the value of sum2, which points to the Fraction that was created in the add: call, why?  Couldn't we have just used sum2 in place of sum for the following code and released sum2 where sum was released?


: Re: Program 7.5 - 7.6 stuck
: skochan March 20, 2009, 07:56:19 PM
Am I correct in stating that sum2's value is a memory address of an Fraction object created & returned  Yes
when sum's add: method was called?sum2 received the result Fraction from sum's add: call  Yes
Then sum was released 
Correct
Then sum was given the value of sum2, which points to the Fraction that was created in the add: call,
That's right

why?  Couldn't we have just used sum2 in place of sum for the following code and released sum2 where sum was released?

I'm not sure I follow this. Perhaps write out the code for me.  But let me explain again: We need to keep a running total of the sum.  That's done in the variable sum.   Each time through the loop we add the current fraction (in aFraction) and sum together.  The add: method stores the result of the addition in a new Fraction object that it creates, and returns that as the result.  That result represents our new cumulative sum, which we store inside sum2.  We can't store the result from the add: method directly back into sum (which is where we ultimately want to put it), because then we would lose our handle on the previous Fraction stored inside sum and we wouldn't be able to release its memory.  That's a memory leak.  So, we first release the old Fraction in sum, and then assign it the new one from sum2.

I'll keep trying until this is clear.  It's obviously the source of confusion among many readers here.

Cheers,

Steve


: Re: Program 7.5 - 7.6 stuck
: demetri007 March 21, 2009, 08:53:53 PM
I re-read and re-read Program 7.6 and your reply.  I now understand where my confusion lied-- the memory leak, if sum was not released.

Thank you!!!!!!!!! for you help, greatly appreciated.

--Demetri


: Re: Program 7.5 - 7.6 stuck
: skochan March 21, 2009, 10:43:45 PM
Demetri,

I'm glad it clicked!  It's really a fundamental concept
that needs to be grasped to get a handle on
object ownership and memory management.

Cheers,


Steve


: Re: Program 7.5 - 7.6 stuck
: Razz2 March 25, 2009, 04:45:41 PM
OK, I have read everything here and in the book and just want to clarify something... I am going to try this step by step mostly...

sum is a Fraction (Fraction 1 lets say) declared, allocated and initialized in 'main'.

sum2 is declared in main but not initialized or allocated.

<START THE FOR LOOP HERE>

Upon executing the method 'add' for the sum fraction (Fraction 1) the result is a new fraction stored in sum2.

: (Objective-C)
sum2 = [sum add: aFraction]
;

sum2 is now an allocated and initialized fraction (Fraction 2 lets say)

Cool, we have two fractions and therefore two memory areas that at some point could need to be released. (right?)

sum (Fraction 1) is then released leaving us with only the memory used by sum2 (Fraction 2).

: (Objective-C)
[sum release];

(NOTE: I think that without this next line we would have had to release sum2 at some point.?.?)

sum is set to equal sum2

: (Objective-C)
sum = sum2;

So now we again have 2 Fractions BUT have only one Fraction memory area to worry about releasing later, and it can be referred to by either sum or sum2. (Fraction 1 and Fraction 2 are the same value and memory?)

<END THE FOR LOOP HERE>

Once the loop ends technically both sum and sum2 still exist. But, they are equal to each other... meaning they are the same piece of memory with all it's related values and variables.

So, the final release, as you hint in another thread, could be:

: (Objective-C)
[sum release];

or

: (Objective-C)
[sum2 release];

Does that make sense and if not am I in the correct state of mind?



: Re: Program 7.5 - 7.6 stuck
: esc March 25, 2009, 05:17:05 PM
Hi Razz2,

What you outlined makes sense.

Technically, the program deals with 3 fractions (the 3 Fraction class objects are aFraction, sum, and sum2).

If these 3 were not objects, let's say they are type int, then
sum2 = [sum add: aFraction] is like "sum = sum + aFraction".

However, because (these are objects) the add: method returns a fraction and the memory for that fraction is allocated from within the add: method, we need a way to release the return value of add:.

After the first loop, the program releases the (previous) memory that add: allocated.
: (Objective-C)
sum2 = [sum add: aFraction];
[sum release];

After the for loop is over, you are correct, sum and sum2 point to the same object in memory and a release message to either (but only one) would release the (last) memory allocated by add:.

I hope this helps and not confuse any :-)


: Re: Program 7.5 - 7.6 stuck
: mdeh March 25, 2009, 10:52:20 PM
OK, I have read everything here and in the book and just want to clarify something... I am going to try this step by step mostly...

sum is a Fraction (Fraction 1 lets say) declared, allocated and initialized in 'main'.


sum is a variable which  points to an instance of the Fraction class. Just think of sum as an instance of Fraction, which has memory allocated.


sum2 is declared in main but not initialized or allocated.


sum2 is a variable of type Fraction...nothing more.

<START THE FOR LOOP HERE>

Upon executing the method 'add' for the sum fraction (Fraction 1) the result is a new fraction stored in sum2.

sum2 now points to an instance of Fraction which **it did not allocate**, but which was passed to it, and which is **distinct** from sum.


sum2 is now an allocated and initialized fraction (Fraction 2 lets say)

I think this may be somewhat overthinking it and causing confusion. sum2, as I said above is pointing at an instance that was **created** elsewhere and you were simply handed a ref to it.  The key here is that the creation of this particular instance violates one of the rules ( as Steve explains somewhere)...and perhaps understanding that rule might throw some light into this issue. The rule says if you allocate , then you release ( you being the method). So, in this case, sum2 is **handed** a ref to an area of memory that suddenly has become it's  responsibility to manage.


sum (Fraction 1) is then released leaving us with only the memory used by sum2 (Fraction 2).

Do you see **why** you are releasing this? You **could** simply assign sum2 to sum, or even more simply just assign the return from the add: method **directly** to sum. However, in this case, the memory sum **used** to point to ( the *old* instance) just sits in memory without anything pointing to it, and by the rules that you have agreed to( that you will be responsible for releasing what you allocate), will just be left alone. Moreover, once you have *re-pointed* the pointer, there is no way to release this either. That's why all this is done. You **release** sum, then point  it to the instance  sum2 is pointing at. There is now just **one** instance of Fraction ( one area of memory). You can reassign sum2 to your hearts content, and it will not create more memory.



: (Objective-C)
[sum release];


(NOTE: I think that without this next line we would have had to release sum2 at some point.?.?)

NO!! The two are **not** related. You are releasing sum, so that you can point to the **new** instance that was created in the other method and to which  sum2 currently points, and not leak memory. Remember you are doing this because you want sum to hold a running total.  If you were to release sum2, you would be setting the instance ( that contains the running total) to nil,  and the program will crash because sum will now **also** be nil and any message to it will be meaningless.
(in fact, I found the old program and released sum2, and got "EXC_BAD_ACCESS", which is the program trying to access memory that it is not allowed to)

sum is set to equal sum2

: (Objective-C)
sum = sum2;

So now we again have 2 Fractions

Nope!!!  you have **one** instance of Fraction...remember, you released sum. What you **do** have are 2 variables pointing to the **one** instance of Fraction

BUT have only one Fraction memory area to worry about

Yes...but not for the reason you gave.

Once the loop ends technically both sum and sum2 still exist. But, they are equal to each other... meaning they are the same piece of memory with all it's related values and variables.

Not sure what you mean by all related values and variables...at the end of the loop, sum and sum2 are equal, by which I mean they both ref the same instance of Fraction.


So, the final release, as you hint in another thread, could be:

: (Objective-C)
[sum release];

or

: (Objective-C)
[sum2 release];

Yes...but **not** both.

OK...take a deep breath. Here is the big picture.

In one method ( which happens to be a loop) ...you are  starting with an instance of fraction referenced by a variable. In **another** method, you create a second instance of Fraction referenced by another variable. Your task is to store this instance in the **first** variable. So, how do you do this and not leak memory. Answer. Sum2!  Does that make sense now?  Or **I ** could be completely wrong ;D


: Re: Program 7.5 - 7.6 stuck
: mdeh March 25, 2009, 11:09:03 PM

Technically, the program deals with 3 fractions (the 3 Fraction class objects are aFraction, sum, and sum2).

Hi Wendy...Firstly **Congratulations** on becoming the first prodigy of the Kochan book!!!   ;D Clearly a testament to the clarity of Steve's style!!!! 

I am wondering about the *3* objects above. The way I read it there are 2 objects. aFraction, and sum. Sum2 at various times points to an object, but never really asks for any memory itself. So the whole exercise here is to take sum ( an object) , release it, point it to the next object which was generated in another method.....ad infinitum.?? Or am I missing something too. ( I am here at work, so do not have the book with me). 


: Re: Program 7.5 - 7.6 stuck
: Mike March 26, 2009, 11:40:46 AM
Hi Steven,


I think I see. Simplified

repeat lines 1 - 3
1. sum2 = sum + fraction <--- sum2 = current fraction + new fracton
2. sum = nil  <--- because it contain the previous fraction
3. sum = sum2  <--- now it contains the current fraction

Mike



: Re: Program 7.5 - 7.6 stuck
: mdeh March 26, 2009, 11:52:12 AM
Hi Steven,


I think I see. Simplified

repeat lines 1 - 3
1. sum2 = sum + fraction <--- sum2 = current fraction + new fracton
2. sum = nil  <--- because it contain the previous fraction

Well, I agree with your action. But the **reason** you are doing this is **not** because it **points to** a fraction/memory, the reason you set it to nil is because you wish to reassign it to a new instance/fraction/memory and you responsibly release it, so it does not leak.

3. sum = sum2  <--- now it contains the current fraction

sum and sum2 now point to the **same** instance/fraction/memory.


: Re: Program 7.5 - 7.6 stuck
: esc April 02, 2009, 01:07:50 PM
I am wondering about the *3* objects above. The way I read it there are 2 objects. aFraction, and sum. Sum2 at various times points to an object, but never really asks for any memory itself. So the whole exercise here is to take sum ( an object) , release it, point it to the next object which was generated in another method.....ad infinitum.?? Or am I missing something too. ( I am here at work, so do not have the book with me). 

Hi Michael,

I missed your reply until now...sorry for not replying sooner.  You are right -- program 7.6 has 2 (Fraction class) objects (aFraction and sum).  sum2 is only a pointer to the object referenced by sum.


: Re: Program 7.5 - 7.6 stuck
: wellaged37 April 03, 2009, 06:33:59 AM
Some questions about the add: method:
1. Is result a local variable?
2. Is it destroyed as the method returns?
3. If it is destroyed, how can it be returned to the main program?

A separate question:
Let's say that an object is released and deallocated. Is the address to the object held by the pointer zeroed? Or is the memory location of the object zeroed? In other words how is the memory freed-up so that it can be re-used? I noticed that when I am debugging I am not aware of any changes in the Debugger pane's variables when deallocation takes place.

Thanks, John



: Re: Program 7.5 - 7.6 stuck
: skochan April 03, 2009, 06:46:25 AM
John,

Read this thread and see if it answers most, if not all, of your questions:

http://classroomm.com/objective-c/index.php?topic=427.0

Cheers,

Steve


: Re: Program 7.5 - 7.6 stuck
: hdelman April 05, 2009, 11:27:42 PM
I've read this entire thread, as well as the other threads that it references.  I do believe I finally understand it, but one thing is still bothering me. 

Is the code written the way it is for any reason other than to help teach us about memory management?  Otherwise, why not just go back and simplify the add method so that it looks like it did on the top of page 150?  It doesn't allocate the new object - result - and the object sum actually accumulates the sum, which is what we want.  No extra alloc and release, and fewer lines of code.

Howard


: Re: Program 7.5 - 7.6 stuck
: skochan April 06, 2009, 01:11:50 AM
Howard,

That's  a good question!  We modified the add: method because the original version overwrites its receiver with the result of the operation.  The more generalized version returns the result without modifying the receiver or the argument.  Of course, as the designer of the Fraction class (or any class you implement) you can make a pragmatic decision on how a method like that should operate based upon the use of the class in programming applications. 

You could even implement two methods:  add: and addInto:; the first could allocate and return a new Fraction object that represents the sum of the two Fractions, the second could add the Fraction into the receiver, as was done with the first version of the add: method.

Cheers,


Steve Kochan


: Re: Program 7.5 - 7.6 stuck
: hdelman April 06, 2009, 07:11:50 PM
Thanks, Steve, for the response.  I understand your points, and I certainly see the advantage of an add: method that doesn't clobber the original values.  But I keep thinking about this, though, and another thought came to mind.  Might it be less confusing if the result object was created by the main routine, and then passed to the add: method?  For example:

-(void) add: (Fraction *) f save: (Fraction *) result
{   
   int resultNum, resultDenom;
   
   resultNum = (numerator * f.denominator) + (denominator * f.numerator);
   resultDenom = denominator * f.denominator;
   [result setTo: resultNum over: resultDenom];
   [result reduce];
}

Then, in main, I would alloc and init sum2 along with aFraction and sum.  The "for" loop becomes:

   for (i=1; i <= n; ++i){
      [aFraction setTo: 1 over: pow2];
      [sum add: aFraction save: sum2];
      sum = sum2;
      pow2 *= 2;
   }
     
All three instances of Fraction are released at the end.

Seems much clearer, and with no worry about memory leakage.

Howard


: Re: Program 7.5 - 7.6 stuck
: skochan April 06, 2009, 07:33:49 PM
However, take a closer look at your code:

: (Objective-C)
   for (i=1; i <= n; ++i){
      [aFraction setTo: 1 over: pow2];
      [sum add: aFraction save: sum2];
      sum = sum2;      <=======
      pow2 *= 2;
   }

The indicated line is just copying a pointer, and not the the Fraction's instance variables (that is, not its numerator and denominator).  At the end of the assignment, sum and sum2 will point to the same fraction, and the handle to the original sum fraction will be lost, meaning it can't be released later.  Because sum and sum2 will point to the same fraction, the next time through the loop  sum (which is really now sum2 from the last time through the loop) will be added with aFraction and the result stored back into sum2, effectively doing what the first version of the add: method did.

Cheers,

Steve Kochan



: Re: Program 7.5 - 7.6 stuck
: hdelman April 06, 2009, 08:29:55 PM
Got it.  Thanks for being a patient teacher.  I understand it, but it is not intuitive.

H.


: Re: Program 7.5 - 7.6 stuck
: ariel_mirahy April 11, 2009, 03:10:47 PM
My program 7.6 is not working, any ideas why?

Main Program.m
: (Objective-C)
#import "Fraction.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Fraccion *frac1 = [[Fraccion alloc] init];
Fraccion *fracSuma = [[Fraccion alloc] init], *fracSuma2;

int nFraccion, expALa2 = 2;

frac1.numerador = 0;

NSLog(@"\n\nHasta Que Fraccion Sumatoria Deseas Calcular?:\n\n");
scanf ("%i", &nFraccion);

for (int i = 1; i <= nFraccion; ++i)
{
frac1.denominador = expALa2;
fracSuma2 = [fracSuma sumar: frac1];
fracSuma.release;
fracSuma = fracSuma2;
expALa2 *= 2;
}

    NSLog(@"\n\nSe Calcularon %i Fracciones Sumadas, El Resultado Es %g!\n\n", nFraccion, fracSuma.convertirAEntero);

frac1.release;
fracSuma.release;

    [pool drain];
    return 0;
}

Also, instead of releasing the sum in the for loop can we release it directly from the method?, Something like:
: (Objective-C)
-(Fraccion *) sumar: (Fraccion *) f 
{
Fraccion *frac3 = [[Fraccion alloc] init];

int resDenominador, resNumerador;

resNumerador = (numerador * f.denominador) + (denominador * f.numerador);
resDenominador = denominador * f.denominador;

frac3.numerador = resNumerador;
frac3.denominador = resDenominador;
frac3.reducir;

return frac3;

       ]frac3.release;// WE RELEASE IT AFTER IT HAS RETURNED THE VALUE TO US
}


Can We?


: Re: Program 7.5 - 7.6 stuck
: skochan April 11, 2009, 04:43:03 PM
You need to set the fracSuma fraction to an initial value before you enter the loop.  The fact that it's not set is causing a division by zero in the reducir method.

I also noticed the following: you are still reducing the receiver in the sumar: method, which you don't want to do (although this is not causing your error).

You can't release the fraction after you return from the method, as nothing gets executed after the return.  Anyway, releasing from the method would cause the object to be destroyed, which you don't want to happen.

Cheers,

Steve


: Re: Program 7.5 - 7.6 stuck
: ariel_mirahy April 11, 2009, 04:55:28 PM
Thanks Steve, I appreciate your help!

Also, I'm not sure if I understand the memmory leakage of this program:

*sum2 = [sum add: aFraction]; // sum2 is an instance variable, but it is not allocated, so it is just like a postal code that tells you where that information is sent or stored, but when you go and see that information, it gives you an instance variable of the receiver (sum) or allocated in the receiver?, so it basically returned an instance of "result" which is a fraction instance allocated inside the sum instance variable, because sum it is the receiver of the method?

*sum.release; // Are we releasing the whole instance variable of sum or just the one inside the for loop? (because there is a final sum.release; at the end of the whole program).

*sum = sum2 // I don't get this well, if we deallocated sum from the memmory, it is still existing, but without memmory allocation or we totally terminated sum?, if it is the second case how can we store some data into it?


Also, why don't we have to release sum2?, in the previous example, we had to release resultFraction when it stored result...

Thanks!



: Re: Program 7.5 - 7.6 stuck
: skochan April 11, 2009, 05:28:52 PM
Please read the entire thread, as it attempts to answer all your questions.  If you've read the thread and still have these same questions, let me know and I'll have another go at it.


Cheers,

Steve Kochan


: Re: Program 7.5 - 7.6 stuck
: ariel_mirahy April 11, 2009, 05:35:40 PM
Please read the entire thread, as it attempts to answer all your questions.  If you've read the thread and still have these same questions, let me know and I'll have another go at it.


Cheers,

Steve Kochan


Thanks Steve,

Yes, you are right, I will attempt to read the whole thread, I just wanted to know if I had the idea first, which obviously i don't due to your answer, Thank You!  ;D


: Re: Program 7.5 - 7.6 stuck
: ariel_mirahy April 11, 2009, 11:56:43 PM
Thanks Steve,

Yes, you are right, I will attempt to read the whole thread, I just wanted to know if I had the idea first, which obviously i don't due to your answer, Thank You!  ;D

OK, so it definitely helped to read the entire thread first, but to be completely sure, I still need to ask.

a) Can the code be:

: (Objective-C)
sum2 = [sum add: aFraction];
sum2.release
sum = sum2 // Can we still use sum2 info or we cant because it has been destroyed (released)?

b) If we can't use sum2 info after the object has been destroyed, then how can we assign sum2 to sum after it has been destroyed (released)?:

: (Objective-C)
sum2 = [sum add: aFraction];
sum.release // Here we release sum
sum = sum2 //Here we assign sum2 to sum after that sum has been destroyed (released)


P.S. I know that case 'a' can't be done, but then how do you explain case 'a' with case 'b'?


: Re: Program 7.5 - 7.6 stuck
: skochan April 12, 2009, 04:03:09 AM
In case 'a', sum2 is released, meaning the fraction object it referenced is no longer valid; it has been destroyed.  You can't use the value of sum2 after that in the program (without reassigning it a new value) as it no longer references a valid object.

In case 'b', sum is released, so the fraction object it referenced is no longer valid.  The assignment that follows sets sum now pointing to the same fraction object that sum2 references.  That is the newly-allocated fraction that the add: method just returned.

Please re-read this explanation and the thread until you understand this sequence; it's critical.  A good way to learn this (as has been pointed out by other forum members) is to draw the fractions out on paper and trace through the operation of the code.

Cheers,

Steve K.


: Re: Program 7.5 - 7.6 stuck
: ariel_mirahy April 12, 2009, 11:03:50 AM
In case 'b', sum is released, so the fraction object it reference is no longer valid. 

Thats the source of my confusion, if sum is released and the fraction object is no longer valid, then sum2 is pointing to where?, to an invalid fraction objet that no longer exists?.

Sorry Steve, this might be a nightmare for you, but i just don't get it, I know you are doing all the things you can possibly do to me for understand, I tried to make a drawing, but I just couldn't make it..., would it be to much to ask you for an image of your drawing or maybe a video on YouTube?

Thanks in advance Steve!


: Re: Program 7.5 - 7.6 stuck
: skochan April 12, 2009, 11:26:55 AM
Let's look at the three key statements in the loop one at a time:

1.
: (Objective-C)
sum2 = [sum add: aFraction];

This calls the add: method, passing the argument aFraction.  Inside that method, aFraction is added with the receiver (sum), and the result is stored inside the fraction result that is allocated inside the add: method.   The fraction that is returned by the add: method is stored inside the variable sum2 by the assignment statement. Make sure you understand this before you go on to the next step here.

2.
: (Objective-C)
[sum release];

This releases the memory taken by the sum fraction.  Originally, this was the fraction we allocated inside main when the program started execution.  However, this variable is modified each time through the loop (by the statement that follows) to point to a different fraction: the one that the add: method returns.

3.
: (Objective-C)
sum = sum2;

This takes the reference to the fraction that the add: method returned (which was the fraction we called result inside the add: method) and that we assigned to sum2 in #1 above, and simply copies it into sum.  This is in preparation for the next iteration through the loop.  At the end of this statement, sum and sum2 both point to the same fraction object, which is the one that the add: method allocated and returned.

Go back to step 1 and repeat for the next iteration. 

I hope this helps.  If not, it's on to YouTube!!    :D

Cheers,

Steve




The diagram would be similar to the one at the top of this thread.


: Re: Program 7.5 - 7.6 stuck
: ariel_mirahy April 12, 2009, 12:18:14 PM
OK, I really GOT it now, I think I went more complex..., thanks Steve!.

Just for the people who still doesn't get it, sum2 is pointing to the result fraction and not to the sum fraction. Then, we release sum because if we don't there won't be an opportunity later to release it + we don't need sum no more at this time. Then we want that sum takes the value of the result fraction because we are doing some other sums, but where is it stored the result fraction? it is stored in sum2 (first step). After aFraction has changed its denominator we want to do another sum, sum now has the value of the result and and we will be adding sum's value (result's value) and currently aFraction value to a new created object (the new result object) and point the new result object to sum2. After all sums are made (the loop is over) we want to release the object (result) that is pointed by to variables sum and sum2, so either releasing sum or sum2 will release the result object. As you can see no objects are still allocated in the memory.

In program 7.5 we released the result fraction (as we would normally do), but in program 7.6, 1 object is pointed by 2 variables so either releasing 1 variable will release the object and there wont be any objects allocated.

P.S. Steve, you are my best writer ever!.


: Re: Program 7.5 - 7.6 stuck
: skochan April 12, 2009, 12:57:45 PM
P.S. Steve, you are my best writer ever!.

Gee, thanks!  :o

Steve


: Re: Program 7.5 - 7.6 stuck
: ARMIZZZ April 12, 2009, 02:11:34 PM
Let's look at the three key statements in the loop one at a time:

1.
: (Objective-C)
sum2 = [sum add: aFraction];

This calls the add: method, passing the argument aFraction.  Inside that method, aFraction is added with the receiver (sum), and the result is stored inside the fraction result that is allocated inside the add: method.   The fraction that is returned by the add: method is stored inside the variable sum2 by the assignment statement. Make sure you understand this before you go on to the next step here.

2.
: (Objective-C)
[sum release];

This releases the memory taken by the sum fraction.  Originally, this was the fraction we allocated inside main when the program started execution.  However, this variable is modified each time through the loop (by the statement that follows) to point to a different fraction: the one that the add: method returns.

3.
: (Objective-C)
sum = sum2;

This takes the reference to the fraction that the add: method returned (which was the fraction we called result inside the add: method) and that we assigned to sum2 in #1 above, and simply copies it into sum.  This is in preparation for the next iteration through the loop.  At the end of this statement, sum and sum2 both point to the same fraction object, which is the one that the add: method allocated and returned.

Go back to step 1 and repeat for the next iteration. 

I hope this helps.  If not, it's on to YouTube!!    :D

Cheers,

Steve




The diagram would be similar to the one at the top of this thread.

Hello Steve,

I've read the whole thread 3 times now, I have just one question:

sum gets released (step 2) before it gets assigned to another value, so the current object of sum will not be leaked into memory..., why doesn't sum2 gets released before each time it changes its value (step 1) so the current object of sum2 (Fraction reslut) doesn't get leaked into memory each time it creates a new result Fraction object (in the add method)?.

That's the only question that I still have...


: Re: Program 7.5 - 7.6 stuck
: skochan April 12, 2009, 02:21:05 PM
sum2 does get released; however, it gets released under the name of sum, because of the assignment of sum2 to sum (you can't over-release an object or you'll crash.  sum and sum2 reference the same object in memory after the assignment and can only be released once).   Remember, there's sort of a one-iteration delay in this loop.  Entering the loop, sum is the fraction object allocated in main.   However, for each subsequent iteration of the loop, sum is the result of the last addition (that is, the result returned by the add: method and assigned to sum2).

Cheers,

Steve Kochan


: Re: Program 7.5 - 7.6 stuck
: MarkReid April 13, 2009, 02:16:56 PM
After reading so many forum posts I really need to find out if what I think it happening is really what's going on.

sum2 is a variable of the type Fraction, it isn't assigned and memory space of it's own and ultimately becomes a pointer to the result of the add:

I don't really understand why the result is stored in sum2 rather than directly in sum however. Would the add: method result in an additional sum Fraction being allocated memory each run through the for loop? If so then where does this occur? From what I see the sum Fraction is only allocated memory when main initially runs so I'm clearly missing something along the way as to why it would be assigned a different memory location which means it can's be done that way.

I know that this is such a crucial point to this chapter and future learning of Objective-C so I really want to understand this before moving on.

Thanks for any help you can give me.


: Re: Program 7.5 - 7.6 stuck
: skochan April 13, 2009, 02:22:42 PM
It's a good thing I stickied this topic as it's turning out to be the critical point for many!

sum2 is a variable of the type Fraction, it isn't assigned any memory space of it's own and ultimately becomes a pointer to the result of the add:

Yes, that's correct!

I don't really understand why the result is stored in sum2 rather than directly in sum however. Would the add: method result in an additional sum Fraction being allocated memory each run through the for loop? If so then where does this occur?

It occurs inside the add: method.  Look at the first line that gets executed inside that method:  A Fraction is allocated and stored in the variable result, which later gets returned from the method and stored inside main in the variable sum2.

Hope this helps!

Cheers,

Steve


: Re: Program 7.5 - 7.6 stuck
: MarkReid April 14, 2009, 07:09:01 AM
Thanks Steve. I think I've got it now.

Does this sound right? Sum2 is assigned rather than sum because if the result was assigned to sum. Failure to do it this way would result in sum losing it's reference to it's initial allocation of memory, the memory allocated in main, before it has released it therefore creating a memory leak. There would be no way to release the memory after assigning result to sum because there would be nothing that pointed to it at that point.

Is that all I'm looking to get from section 7.5 and 7.6? That there can be more than one pointer to a memory location, sometimes these are needed to ensure you can release memory and you need to give back what you use as soon as you're done using it else you create memory leaks?


: Re: Program 7.5 - 7.6 stuck
: skochan April 14, 2009, 07:19:41 AM
Does this sound right? Sum2 is assigned rather than sum because if the result was assigned to sum. Failure to do it this way would result in sum losing it's reference to it's initial allocation of memory, the memory allocated in main, before it has released it therefore creating a memory leak. There would be no way to release the memory after assigning result to sum because there would be nothing that pointed to it at that point

Well, that's correct but it's a little more that that.   If you assigned the result of the addition right back to sum, you wouldn't be able to release the last fraction referenced by sum.  The first time through the loop, that is the fraction explicitly allocated in main.  Subsequent times through the loop, that is the fraction return by the add: method the previous time it was called.

The key point to get from these programs is learning how to keep track of your objects to avoid memory leaks.  Understanding what's going on with these fraction objects as far as where they're allocated and how and when they can be released provides the foundation for understanding memory management and how to avoid memory leaks in your applications.

Cheers,

Steve



: Re: Program 7.5 - 7.6 stuck
: MarkReid April 14, 2009, 07:27:47 AM
Steve, thanks for all your help on this one. I feel now that I have a good enough grasp on the topic to move forward and try the exercises for this chapter.


: Re: Program 7.5 - 7.6 stuck
: MarkReid April 15, 2009, 08:02:22 AM
I've just been re-reading chapter 7 and have a question on the 7.5 program example.

In the add method  the line
Fraction *result = [[Fraction alloc] init];
creates an instance of the Fraction class called result, correct? Why is this not called resultFraction?

I notice that in the main.m of this example the result instance is assigned to resultFraction. Is there any reason that this could not have been assigned to result instead?

Another point, is it not possible to [result release]; in main.m to release the Fraction returned by the add: method?

I hope my questions make sense.


: Re: Program 7.5 - 7.6 stuck
: skochan April 15, 2009, 08:11:15 AM
I'm not sure I fully understand your question, but I'll take a shot at it anyway.  The naming of the variables is arbitrary; you can name them anything you want.  Obviously, the case was made in the text for picking meaningful names.   The variable in the add: method could have been named resultFraction, but it wasn't!  If it were named resultFraction it would be a different variable from the similarly-named variable in main. The first would be local to the add: method, the second local to the main function.  As such, they exist in separate name spaces and are completely distinct.

Hope that was the answer to the question you posed!

Cheers,

Steve


: Re: Program 7.5 - 7.6 stuck
: MarkReid April 15, 2009, 08:18:03 AM
So if I'm understanding it correctly result and resultFraction are local variables. result, after being returned from the add: method, needs to be assigned to a variable in main otherwise it wouldn't be accessible within main?

The point I seem to have missed is that the two variables aren't the same. I assumed that when a method returned a value that it was available as a variable within main with the same name as the method returned it as.


: Re: Program 7.5 - 7.6 stuck
: skochan April 15, 2009, 08:26:28 AM
So if I'm understanding it correctly result and resultFraction are local variables. result, after being returned from the add: method, needs to be assigned to a variable in main otherwise it wouldn't be accessible within main?

Yes, that's correct.

The point I seem to have missed is that the two variables aren't the same. I assumed that when a method returned a value that it was available as a variable within main with the same name as the method returned it as.

Reread the discussion on local variables that starts on page 146.

Cheers,

Steve


: Re: Program 7.5 - 7.6 stuck
: MarkReid April 15, 2009, 08:41:11 AM
Reread the discussion on local variables that starts on page 146.

Cheers,

Steve


Got it now thanks. Don't know why but I assumed that because it was an instance of an object that it was somehow different. Good thing I realised the mistake early on, might have caused bigger problems later.  :)


: Re: Program 7.5 - 7.6 stuck
: MrTech40 May 01, 2009, 07:23:11 PM
Hey guys, this is my first post.

I've been having a lot of trouble with the concept of memory leaking. I read the thread and drew some flow charts to try and understand the concept.

Please tell me if I understand this concept correctly.

sum is a pointer to result (the Fraction object).
sum2 is assigned the value of sum
therefore sum2 also points to result.
sum is released
sum = sum2

if sum was not released, it cannot be released later because there is no pointer pointing to sum.

Here is my graphic representation

For loop begins

1st iteration of the loop
---------
| sum |    *The box represents an object that was the result of the add: method
---------

2nd iteration of the loop
---------
| sum |    *this is the same box as above
---------

-------------
| newsum|   *this is a new object that was created as a result of the add: method.  *Note the original **sum** exists
-------------

3rd iteration
---------
| sum |   
---------

-------------
| newsum| 
-------------

--------------
| newsum2|    *this is the third **sum** that was created as a result of the add: method.  *Note the above **sum** objects
--------------

So on and so forth

So basically what is happening is that if **sum** is not released a new **sum** object is being created during each iteration of the for loop?
The previous **sum** objects cannot be released or accessed because nothing is pointing/referencing them?

This is a memory leak?
My graphic representation above represents how memory leaks can potentially take up so much space?

Thank you so much everyone for trying to explain!! You have all been a wonderful help!! ;)

Robert





: Re: Program 7.5 - 7.6 stuck
: skochan May 02, 2009, 12:06:03 AM
I'm not sure I follow your diagrams; I would have preferred if you would have used the variable names as in the program.  However, your verbal description seems accurate about having to release the object before we lose the handle to it.

Cheers,

Steve Kochan


: Re: Program 7.5 - 7.6 stuck
: MrTech40 May 02, 2009, 08:49:50 AM
@skochan

I will do my best to try and explain it again.

Here is what I think is happening:
Please correct me if I am wrong

1. **sum** is the result of the [sum add: aFraction] call
    in other words sum = sum + aFraction

2. **result** is the object that is returned from the add: method. However **result** is returned as a new object. Again please correct me if I am wrong.
    so again in other words: sum = sum + result

3. Sum is now pointing/referencing a place in memory where the running total is (referencing to a place where the add: method returned its object)

4. **result** canot be released because it does not have a poiner, so it is assigned to a variable that can point to **result** In this case **result** is returned as a new object from the add: method. The reult of the add: method is assigned to **sum**.

5. sum2 is assigned the value of sum. sum2 and sum are both pointers to the new object that was created as a result of the add: method.

6. therefore sum2 is now pointing to the same location in memory as sum?

7. sum is released because if it isn't, after the next iteration of the for loop, the previous **sum** will not be able to be released because a new object has been created and **sum** is pointing to the newly created object and nothing is referencing the previous **sum** (the previous object).  Am I correct about this?

8. After being released sum is now assigned the value of sum2. 


The following diagram is assuming that **sum** was never released. I am trying to depict what happens if **sum** is not released.

1st iteration of the for loop:

----------
|object |    *The box represents an object that was the result of the add: method and was stored in sum
----------

----------                                     ----------
|object | -------stored in-------->|  sum  |  *sum now points to object. object is stored somewhere in memory
----------                                     ----------

----------                                     --------
| sum2 | assigned the value of | sum |  *sum2 now points to the same place as sum
----------                                     --------

2nd iteration of the for loop

----------
|object | *this is the previous object that was created in the iteration of the for loop
----------    it cannot be released because there is nothing pointin/referencing it.

----------
|object | *this is the new object that was created because of the second iteration of the for loop
----------  *we now have 2 objects because the previous object did not release sum.

----------                                     ----------
|object | -------stored in-------->|  sum  |  *sum now points to object. object is stored somewhere in memory
----------                                     ----------  *this is the newly created object being stored. NOT the old object

----------                                     --------
| sum2 | assigned the value of | sum |  *sum2 now points to the same place as sum
----------                                     --------

**Now neither sum nor sum2 are referencing/pointing to the previously created object (the previous sum)
**the previous **sum** cannot be released because nothing is pointing to it.
**a new sum is not being created after each iteration. A new object is created from the add: method and sum points to the new object that was created.
**When **sum** is released, it releases the memory that it is pointing to.

so on and so forth until the for loop terminates

I hope you can understand what I am trying to say a little better

Thanks again,

Robert


: Re: Program 7.5 - 7.6 stuck
: skochan May 02, 2009, 12:04:53 PM
I'm sorry, but I'm not quite getting the diagram.  I believe the diagram is not accurate, at least with respect to the first iteration.  For example, sum2 is not assigned the value of sumsum2 is assigned the result from the add: method, which is the Fraction object that is allocated and returned from inside that method.

Why don't you make that change to the diagram and then post again.

Cheers,

Steve Kochan


: Re: Program 7.5 - 7.6 stuck
: MrTech40 May 02, 2009, 04:29:42 PM
Third time's the charm.

Before I go into my diagrams, I want to ask if a memory leak is when an object is created and it cannot be released? It can't be released because nothing points to it?

If the above statement is correct, than I understand what a memory leak is.

This is what I think is happening when memory is leaked...

1st iteration of the for loop
----------
|object |    *The box represents an object that was the result of the add: method and was stored in sum (sum was the receiver
----------      of the add: message)

----------                                 ----------
|object | -------stored in--------> |  sum  |  *sum now points to object. object is stored somewhere in memory.
----------                                 ----------        Correct me if I'm wrong.

----------                                 ---------------------------
| sum2 | assigned the value of    | sum add: aFraction  |   *sum points to **result** Since sum2 is assigned
----------                                 ---------------------------    [sum add: aFraction], sum2 now points to the Fraction object that
                                                                                   was returned from the add: method.



At this point I want to ask if sum2 holds the actual value of **result** ( a numerical value) or if sum2 is a pointer to the object that was created from the add: method?
                                                                                                                         ---------
Assuming that **sum** was never released, after each iteration of the loop would a new |object |  will be created because
the previous one was never released?                                                                      ---------   
                 ---------                                                                                                           
After a new |object |  is created, sum points to the newly created object. Nothing points to the previous sum, therefore it can't be
released.     ---------

Please correct any of my mistakes.

Assuming sum doesnt get released, after each iteration of the for loop, does a new **sum** get created ( a new sum object) or does a new object from the add: method get created. For example after 5 iterations, will I have 5 **sum** objects or will I have 1 **sum** and 5 objects created as a result of the add: method?

Thank you for all of your time. I hope you understand what I am trying to explain.

Robert


: Re: Program 7.5 - 7.6 stuck
: skochan May 02, 2009, 04:50:07 PM
Before I go into my diagrams, I want to ask if a memory leak is when an object is created and it cannot be released? It can't be released because nothing points to it?

Yes, that will definitely create a memory leak.  Memory leakage is also created by allocating objects and never releasing them when you're done using them.  For example, you allocate objects and add them to an array.  You then release the array, but you don't release the individual objects you allocated, even though you're done using them.  That would be considered a memory leak as well (at least I would consider it a leak).   

You can look it in mathematical terms.  If you have x objects allocated when you perform some event, you should have x objects allocated when you're done with that event, assuming here that all the objects that were allocated as part of handling that event are no longer needed.

Now I'll look at the rest of your post.   :) :)

Steve



: Re: Program 7.5 - 7.6 stuck
: skochan May 02, 2009, 05:16:56 PM
1st iteration of the for loop
----------
|object |    *The box represents an object that was the result of the add: method and was stored in sum (sum was the receiver
----------      of the add: message)

Yes, sum was the receiver, but the result is stored in sum2, not sum

----------                                 ----------
|object | -------stored in--------> |  sum  |  *sum now points to object. object is stored somewhere in memory.
----------                                 ----------        Correct me if I'm wrong.

sum still points to the original Fraction object allocated at the start of main.

----------                                 ---------------------------
| sum2 | assigned the value of    | sum add: aFraction  |   *sum points to **result** Since sum2 is assigned
----------                                 ---------------------------    [sum add: aFraction], sum2 now points to the Fraction object that
                                                                                   was returned from the add: method.

sum still points to the original Fraction object allocated at the start of main.


At this point I want to ask if sum2 holds the actual value of **result** ( a numerical value) or if sum2 is a pointer to the object that was created from the add: method?

It holds a pointer to the object's data in memory.
                                                                                                                         ---------
Assuming that **sum** was never released, after each iteration of the loop would a new |object |  will be created because
the previous one was never released?
   

Yes, we have to release the fraction allocated in the add: method the last time it was called.                                                                   ---------   
                 ---------                                                                                                           
After a new |object |  is created, sum points to the newly created object. Nothing points to the previous sum, therefore it can't be
released.     ---------

We have to be careful about what part of the loop we're talking about here.  After the first iteration, sum points to the Fraction object allocated the last time the add: method was called.  Here's the sequence again of the key statements in the loop:

: (Objective-C)
  ...
sum2 = [sum add: aFraction];

The add: method adds the two Fractions sum and aFraction together, storing the result in an allocated Fraction object called result in the add: method.   The add: method returns that allocated Fraction, which gets stored in main inside the variable sum2.

The first time through this loop, sum is the Fraction that we allocated at the start of main.

: (Objective-C)
[sum free];

The first time through the loop, we free the Fraction object we allocated in main.   sum2 still points to the sum returned from the add: method in the previous statement.

: (Objective-C)
sum = sum2;

We transfer the reference to the Fraction object that's stored in sum2, which is the Fraction object we allocated inside the add method, to sum.  Now sum and sum2 both reference the same Fraction object; the one we allocated in the add: method.  This assignment is being done in preparation for the next iteration through the loop.  We were careful to release the previous Fraction object referenced by sum before overwriting its value before we lost the reference.  Otherwise, we would have created a memory leak.

: (Objective-C)
    pow2 *= 2;
}

The loop continues execution.   At the top of the loop, after setting aFraction, this line is executed again:

: (Objective-C)
  ...
sum2 = [sum add: aFraction];

Again, the Fractions sum and aFraction are added together and the resulting fraction that is allocated by the add: methods gets returned and stored in sum2.  Note that for the second and subsequent iterations that the value of sum is the value that was returned by the add: method the last time it was called.

I hope this helps!

Cheers,

Steve





: Re: Program 7.5 - 7.6 stuck
: MrTech40 May 02, 2009, 06:51:48 PM
Everything is crystal clear now!! :)  ;)  :D  ;D  8)

Thank you for taking the time to explain it to me!!

Robert


: Re: Program 7.5 - 7.6 stuck
: Crivo May 29, 2009, 08:30:36 AM
I did get stuck on this as well, and my many questions have been answered.
Thank you all for participating in this discussion.


: Re: Program 7.5 - 7.6 stuck
: scutter7282 June 02, 2009, 01:45:54 PM
Thanks as well for that long thread.  My question is why and what it means when both sum is allocated and sum2 is on the same line?

Fraction *sum = [[Fraction alloc] init], *sum2;

Is this shorthand for

Fraction *sum = [[Fraction alloc] init];
Fraction *sum2;

or for

Fraction *sum = [[Fraction alloc] init];
Fraction *sum2;
sum = sum2;

or just

Fraction *sum = [[Fraction alloc] init];
sum = sum2;


I believe this is the first time in the textbook that I've seen something besides and alloc/init expression on the other side of the assignment operator to a new instance of a class.  And if it is shorthand, why not combine all three instances in one statement (I guess because they're similar in name/use)? 

Thanks, I want to make sure I understand the syntax.





: Re: Program 7.5 - 7.6 stuck
: skochan June 02, 2009, 02:41:43 PM
Choice #1:

: (Objective-C)
Fraction *sum = [[Fraction alloc] init];
Fraction *sum2;

Just as

: (Objective-C)
int  x1 = 100, x2;

is equivalent to

: (Objective-C)
int x1 = 100;
int x2;

Cheers,

Steve Kochan


: Re: Program 7.5 - 7.6 stuck
: scutter7282 June 02, 2009, 02:45:06 PM
Thanks for clarifying.  It makes sense, but in the mess of this long thread, I was wondering if I no longer understood that declaration...

Really appreciate your responses and your book! At some point you ought to charge a small fee for the forum when you gives such personal attention to user questions!


: Re: Program 7.5 - 7.6 stuck
: skochan June 02, 2009, 03:17:22 PM
Maybe I should add one of those "donate" buttons.    8)


: Re: Program 7.5 - 7.6 stuck
: uriash July 20, 2009, 06:48:29 AM
Hi,
I still can't understand something..
in chapter 8 it is mentioned that:
"release sometimes gives up the memory an object used, and sometimes it
doesn’t. It gives up the memory taken by an object only if no one else is referencing that object."
So, if we released only *sum and not *sum2, doesn't it means that it hadn't given up the memory taken, since there is still a reference (sum2) to it?
U. :P


: Re: Program 7.5 - 7.6 stuck
: skochan July 20, 2009, 07:22:34 AM
Without automatic garbage collection you have to send a retain message to an object to explicitly tell the system that there is a reference to that object.  As noted in Chapter 17, this has the effect of increasing the object's retain count, which indicates the number of times the object is being referenced, and which normally starts at 1 when an object is created.  

When you send a release message to an object, that object's retain count gets decremented by 1.  When it reaches 0, the object gets destroyed (via the dealloc method).  

Again, the retain/release mechanism is not needed when using garbage collection, and it's ignored if garbage collection is enabled.  However, since the iPhone and iPod Touch don't support garbage colleciton, you have to manually handle memory management in this manner.

You can read ahead to Chapter 17 if you want more details.

Cheers,

Steve Kochan


: Re: Program 7.5 - 7.6 stuck
: uriash July 20, 2009, 07:48:38 AM
thanks!


: Re: Program 7.5 - 7.6 stuck
: TheWoz July 24, 2009, 02:04:11 PM
Even though there are already tons of explanations in this topic, I made an overview of the objects being created and freed. I hope this helps anyone that still doesn't get it. There's only 1 thing I don't fully understand. When you use the add: method to add the value of aFraction to sum, the value of aFraction is, obviously, added to sum. Next, this is assigned to sum2. And then sum is freed. I see you don't delete the first sum object(which I call Object B), but the one created in the for loop. Anyway, I don't see how it's possible to use the same names for objects. You delete an object in the for loop(which I call Object B1), but how does the compiler knows this is not the first sum object(which I call Object B)? Are these local object or something?

Here it is: http://img197.imageshack.us/img197/762/picture4nes.png (http://img197.imageshack.us/img197/762/picture4nes.png)

PS 1: my apologies for my sometimes poor English, but, hey, what do you expect from a Belgian? :-p
PS 2: I might interpret this totally wrong, could someone tell me this if that is the case?  ;D


: Re: Program 7.5 - 7.6 stuck
: TheWoz July 25, 2009, 02:22:01 AM
No one? :-( I want to make sure I get it before moving on in the book, so please...


: Re: Program 7.5 - 7.6 stuck
: tbarreca August 11, 2009, 05:19:36 PM
Just worked my way through this section, then found this set of posts.  Very useful.  Thanks to all.


: Re: Program 7.5 - 7.6 stuck
: stringchopper November 13, 2009, 10:00:36 AM
I'm new to mac and objective-c, but when I first studied pointers while learning c (windows environment), I had a hard time.  It all became clear when I delved into assembly programming (Kip Irvine's book "Intel Assembly Programming").  Then I realized the obvious, that pointers are just a 4-byte address (on 32 bit machines).  This address is "followed" to get to the specific starting point in memory that actually holds the values of the object. 

I highly recommend at least a cursory study of assembly.  Though this AT&T syntax on the mac is a bit rough to the eyes.  I guess in the end, it's all op-code!



: Re: Program 7.5 - 7.6 stuck
: nata11 January 24, 2010, 04:44:49 PM
My version of the 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;
   
   printf("Address fraction %u\n",aFraction);
   printf("Address sum %u\n",sum);
   printf("Address sum2 %u\n",sum2);
   
   [sum setTo:0 over:1];
   
   NSLog (@"Enter your value for n: ");
   scanf("%i",&n);
   
   pow2 = 2;
   
   for (i = 1; i <= n; ++i) {
      
      printf("-----Iteration %i-----\n", i);
      [aFraction setTo:i over:pow2];
      printf("Address fraction %u\n",aFraction);
      sum2 = [sum add:aFraction];
      printf("Address sum2 %u\n",sum2);
      [sum release];
      printf("Address sum %u\n",sum);
      sum = sum2;
      printf("Address sum %u\n",sum);
      printf("Address sum2 %u\n",sum2);
      pow2 *= 2;
   }
   NSLog (@"After %i iterations, the sum is %g", n, [sum convertToNum]);
   
   [aFraction release];
   [sum release];
   
   [pool drain];
   return 0;
}

My result:

This GDB was configured as "x86_64-apple-darwin".tty /dev/ttys000
Loading program into debugger…
Program loaded.
run
[Switching to process 615]
Running…
Address fraction 1099824
Address sum 1099888
Address sum2 0
2010-01-24 15:25:56.781 FractionTest[615:a0f] Enter your value for n:
3
-----Iteration 1-----
Address fraction 1099824
Address sum2 1102880
Address sum 1099888
Address sum 1102880
Address sum2 1102880
-----Iteration 2-----
Address fraction 1099824
Address sum2 1099888
Address sum 1102880
Address sum 1099888
Address sum2 1099888
-----Iteration 3-----
Address fraction 1099824
Address sum2 1102880
Address sum 1099888
Address sum 1102880
Address sum2 1102880
2010-01-24 15:26:07.545 FractionTest[615:a0f] After 3 iterations, the sum is 1.375

Debugger stopped.
Program exited with status value:0.

My 2 cents:
For those who are still slightly confused this is my explanation (and this is also to cement my understanding). I hope it helps somebody in future. There were two issues which we were bothering me in this example. One was the declaration of :

Fraction *sum = [[Fraction alloc] init], *sum2;

One of the posts in this long thread answered that question for me. But I was still confused with the sum / sum2 object / memory interaction. So here is what I could come up with.

One of the main points I think is the fact that when you declare :

Fraction *sum = [[Fraction alloc] init], *sum2;

you are saying that *sum is a pointer variable (had to lookup pointers!) which will store the address of a new Fraction object. You are also saying allocate some space for it now. On my machine the location allocated to it was 1099888 (please see code and code results above). But with *sum2 you are just saying its a pointer to a Fraction object address to be stored in future and hence there is no address allocated to it now.

Then when you enter the first iteration *sum2 gets allocated by the system and receives the address 1102880 and a Fraction object gets stored starting at that address upon execution of this statement:

sum2 = [sum add:aFraction];


So in the next statement when you say [sum release] this lets the system know that the location 1099888 is free now to store any other object.

In the next statement sum = sum2 we are saying store the address of sum2 Fraction object in pointer variable *sum, so the value of *sum becomes the address of the object (which is *sum2=1102880) returned by [sum add:aFraction].

The next time when the iteration runs, address location which is freed up in the last iteration - 1099888 - gets allocated for the new sum2 Fraction object.

This swapping of address locations keeps happening until inside the last iteration when you release *sum you are releasing address location 1099888 and then assigning *sum to *sum2 which is 1102880. So both pointer variables point to 1102880 which is released in the final [sum release]. There is no need to release sum2 since its pointing to same memory location.

I hope this helps and I hoping that this example is clarified in more detail in next edition of the book.


: Re: Program 7.5 - 7.6 stuck
: Ludagoo January 26, 2010, 05:12:15 PM
Thanx for the incredible thread and forum first time i had to use it i am sure i will use it again


: Re: Program 7.5 - 7.6 stuck
: egb March 04, 2010, 12:33:43 AM
When I first read the code for Program 7.6, I understood why you didn't have to allocate and initialize sum2, as that is handled within the add method (per pages 150 and 151).

However, I thought that [sum2 release] was missing from the code. Reading through this discussion has helped me figure out why that wasn't the case.

I was thinking of sum and sum2 as variables in the same sense of an int variable; that is, that they were containers for the actual Fraction instances. So when you code "sum = sum2" I was reading it as "assign all of the components of sum the same values as the components of sum2." This thread helped me understand that sum and sum2 are just pointers, and "sum = sum2" means "make sum point at the same thing that sum2 is pointing at."

Going back to the old car analogy from the earliest chapters, it would be like saying: "herCar = myCar"
It's not that her car is identical to mine, it's that the beat-up old Honda in our garage can be referred to as herCar OR myCar, 'cause they are the same car! And we only have to get rid of (i.e. release) one Car from our garage when we are done with it...

I think some of the confusion, at least for me, might arise from the fact that we don't really get into pointers until chapters 8 and 13.



: Re: Program 7.5 - 7.6 stuck
: skochan March 05, 2010, 03:10:44 PM
think some of the confusion, at least for me, might arise from the fact that we don't really get into pointers until chapters 8 and 13

Yes, in the next edition of this book I will add some diagrams and make sure the idea that the object variable holds a pointer to where the object's data is actually stored in memory.  I'll be using the types of diagrams I put at the start of this post.  I didn't want to get bogged down with the idea of pointers, but I think the approach I used in Chapter 8 (with the diagrams) should be introduced earlier in Chapter 7.

The great thing about this forum is that it has helped me to learn where people are getting confused or need additional explanations of things.  I'll be able to capitalize on all this in the next edition of the text.

Cheers,


Steve Kochan



: Re: Program 7.5 - 7.6 stuck
: macgruder April 22, 2010, 01:46:34 AM
Hello Stephen,
Thanks for your great book. Sorry to resurrect this thread after the long discussion:

My understanding is the reason that we need to do this release of memory is because of the memory allocated to the fraction inside the add method and returned. The logic is this:


: (Objective-C)
sum2 = [sum add: aFraction];

Then "add" says: "Hey, I'm creating a new object 'result', let's put that at memory location 2211, and return it" (say)

Then sum2 gets the return and says: "OK. I point to location 2211".

But if we again do
: (Objective-C)
sum2 = [sum add: aFraction];
"Add" says the say thing but the new object is at a new free location say 2257. So when we do

[release sum2] we can't release 2211 because now sum2 'points' to 2257, and there's your memory leak.

So a rule of thumb would be to release an object before you assign it a new place in the memory (via a method for example), and in a loop such as your 'add' example, the only way to do this is created a 'holding' variable.

Am I on the right track here?



: Re: Program 7.5 - 7.6 stuck
: skochan April 22, 2010, 03:35:10 AM
Yes, your analysis is correct.  In general, the add: method itself should be responsible for  releasing that newly-allocated Fraction object.  The easiest way to do that would be with the autorelease pool, which is discussed later in the book.

Cheers,

Steve Kochan 


: Re: Program 7.5 - 7.6 stuck
: marks April 25, 2010, 08:49:20 AM
So, the object result in add: method and the object resultFraction in the main section are pointing to the same memory? What happen if I go alloc & init in both MAIN program and Implement section?

I tried that, and the program finished running without any error. But is this will affect the memory allocation?

implementation section - add: method
: (Objective-C)
Fraction *result = [[Fraction alloc] init]; 

Main
: (Objective-C)
Fraction *resultFraction = [[Fraction alloc] init]; 

Thanks,
Mark


: Re: Program 7.5 - 7.6 stuck
: marks May 22, 2010, 06:22:40 AM
In Program 7.5, when I try to run "Build and Analyze", it point to the line [resultFraction release]; and said, "Incorrect decrement of the reference count of an object is not owned at this point by the caller".

What does this mean? Does it consider an error or warning that the memory were not release properly?

Thanks,
Mark


: Re: Program 7.5 - 7.6 stuck
: skochan May 22, 2010, 09:29:27 AM
It's an imperfect analysis.  It doesn't know that the object was allocated in the add: method.

Cheers,

Steve Kocnan


: Re: Program 7.5 - 7.6 stuck
: Jack June 13, 2010, 10:03:32 PM
I know this has been explained many times already in this thread, but I thought it would be helpful to have yet another explanation.  The key concept for me was the distinction between a variable and the object it points to.  In my comments, I have followed the analogy comparing a class to a factory.  So every time alloc and init are called, a new Fraction object is created with a unique identifying number, like a serial number.  This made it easier for me to keep track of which variable was pointing to which object.  Hope this explanation is helpful.

Jack

: (Objective-C)
#import "Fraction.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Fraction *aFraction = [[Fraction alloc] init]; //  Fraction01 is created. aFraction points to it.
Fraction *sum = [[Fraction alloc] init], *sum2; //  Fraction02 is created. sum points to it.
//  sum2 doesn't point to anything yet.  it will eventually
//  point to the Fraction object created by the add method.
int i, n, pow2;

[sum setTo:0 over:1];

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]; //  sum2 now points to Fraction03.  Fraction03 was created by the add method
//  ** a new Fraction is created every time the add method is called **
//  sum still points to Fraction02

[sum release]; //  Fraction02 is released.
//  sum needed to release Fraction02 before it could point to Fraction03

sum = sum2; //  now, sum can point to Fraction03
pow2 *= 2;
}

NSLog(@"After %i iterationsm the sum is %g.", n, [sum convertToNum]);
[aFraction release]; //  Fraction01 is released
[sum release]; //  Fraction03 is released

    [pool drain];
    return 0;
}


: Re: Program 7.5 - 7.6 stuck
: anmldr January 01, 2011, 07:35:57 PM
I am back to trying once again to understand the fraction1 app before Steve taught us about the autorelease pool.

I think that I get it now about when to release and not release.

My problem is a little easier, I hope.

If someone provided you with the interface file of their class and you don't have access to the implementation file, how would you know that you would not need to alloc and init  sum2 in main?

i.e.
Fraction *sum2;
instead of
Fraction *sum2 = [[Fraction alloc] init];

Would you know this only if you had the documentation provided by the creator of the fraction class?

Linda


: Re: Program 7.5 - 7.6 stuck
: chuckbo January 10, 2011, 10:23:37 PM
Thank you, Jack, for that description. I finally think I might understand it. (And I was getting very frustrated -- and starting to worry that I had spent too many decades programming in VB and RealBasic to make the switch.) It was really bothering me to see Sum released, and then used; I didn't get that you were releasing the object that it was pointing to.

But here's the reason I'm posting a follow up note. I'm thinking about Sum and Sum2 as pointers to the real objects, and how I would test two objects to see if all of their properties match. If I use the statement
If Sum = Sum2
am I really testing to see if the two variables point to the same object (have the same address)? If I really want to test two fraction objects to see if they match, will I need to individually test every property of the object?

Chuck


: Re: Program 7.5 - 7.6 stuck
: skochan January 25, 2011, 11:09:50 AM
Chuck,

First of all you meant to use == not = in your example!  Second, yes if you test the two variables and they are equal then they identify the same object.   You'll learn later in the book (Chapter 15) that there is a concept of two objects being "identical" and being "equal."   You have control over the latter, so you may want to consider two Fraction objects to be equal if they have the same numerator and denominator (or maybe even if they both reduce to the same value; that is, you might consider 3/4 and 6/8 as being equal).

Cheers,

Steve


: Re: Program 7.5 - 7.6 stuck
: ZimBob March 15, 2011, 10:28:07 AM
Near the top of this thread, Stephen Kochan says:

"In Program 7.6, you end up with both sum and sum2 referencing (pointing to) the same Fraction object in memory.  And you can only release that object's memory once."

I confess to not having read every word of this thread, but I'm pretty sure that this is not true. I think that immediately after: sum2 = [sum add: aFraction], sum2 and sum point to different Fraction objects. Looking at the method add:, it doesn't actually change the object of which it (add:) is a method. sum dontinues to point to the old object. sum2 points to the object returned by add:

The above quoted paragraph created tremendous confusion for me. If it is inaccurate, I would suggest changing it. If I'm totally confused, then I need to know.

Thanks so much.

Bob


: Not passing in Program 7.5
: jcd April 02, 2011, 12:46:23 PM
I believe I understood the concepts, after rewinding 3 times chapters 3 and 7, but I've a problem in 7.5 I couldn't solve for hours.

In my interface section I have the method add:

-(Fraction *) add: (Fraction *) f;

In the implementation section, the method is the following:

-(Fraction *) add: (Fraction *) f // f is just a placeholder, anything goes
 
    {

        Fraction *addTwoFractions = [[Fraction alloc]init];
     
        int resultNumerator , resultDenominator;
       
        resultNumerator = numerator * f.denominator + denominator * f.numerator;
        resultDenominator = denominator * f.denominator;
       
        [addTwoFractions setNumerator: resultNumerator andDenominator: resultDenominator];
        [addTwoFractions reduce];
        return addTwoFractions;
   
    }

In the main program, I have:

    int topNumber,bottomNumber;
   
    Fraction *firstFraction = [[Fraction alloc] init];
    Fraction *secondFraction = [[Fraction alloc] init];
    Fraction *thirdFraction;
   
    NSLog(@"First Fraction?");
    scanf("%i,%i",&topNumber,&bottomNumber);
   
    [firstFraction setNumerator:topNumber andDenominator:bottomNumber];

    NSLog(@"Second Fraction?");
    scanf("%i,%i",&topNumber,&bottomNumber);
   
    [secondFraction setNumerator:topNumber andDenominator:bottomNumber];
   
    thirdFraction = [firstFraction add:secondFraction];
   
And I always get an error in this last line: "  Assigning to 'Fraction *' from incompatible type void.  "

Well, the type is not void, and I don't get any error in the @interface or @implementation files...

Any Help?


: Re: Program 7.5 - 7.6 stuck
: skochan April 02, 2011, 12:55:40 PM
The earlier version of the  add: method was a void method, so that's suspicious.  Try doing a Clean and rebuilding the project.

Cheers,

Steve


: Re: Program 7.5 - 7.6 stuck
: jcd April 02, 2011, 01:33:28 PM
The earlier version of the  add: method was a void method, so that's suspicious.  Try doing a Clean and rebuilding the project.

Cheers,

Steve

Thanks, Steve.

The clean didn't work but your suspicion told me to change the name of the method to add2... and it worked.

So, I believe it's a XCode bug.

Thanks again for your help.

jcd


: Re: Program 7.5 - 7.6 stuck
: Luis.Z May 31, 2011, 06:17:43 AM
Steve, congratulations for this awesome book and best of luck in the upcoming launch!

The Q&A of this topic is centered at "sum" and "sum2". But my question is regarding "result": shouldn't we release result at the end of the method?

Thanks and regards,
luis


: Re: Program 7.5 - 7.6 stuck
: gerhard August 08, 2011, 04:30:31 PM
It's an imperfect analysis.  It doesn't know that the object was allocated in the add: method.

Cheers,

Steve Kocnan

Hi, Steve

First of all, thank you for writing this great book!

I'm comfortable with the explanation that you and others have provided for the memory allocation in this example (7.6). However, it seems to me that the example does throw more curve balls than what your book's intention is. For instance, as was previously pointed out, the Analyzer doesn't approve either... As you can see in the attached image focussing on the 'add' method, the analyzer indeed complains that it violates the naming convention in the Memory Management Guide for Cocoa.  It seems to me you've outwitted not only your readers, but also Apple! I guess CLEVER programming isn't always appreciated!

Cheers

Gerhard






: Re: Program 7.5 - 7.6 stuck
: skochan August 09, 2011, 09:50:45 AM
The analyzer is following standard naming conventions.  However, those are "conventions" and not requirements.   Later in the book you see how to use "autorelease" to handle this correctly and that satisfies the analyzer as well (see the note on page 142).

Cheers,

Steve


: Re: Program 7.5 - 7.6 stuck
: john67 August 09, 2011, 06:10:28 PM
Steve, congratulations for this awesome book and best of luck in the upcoming launch!

The Q&A of this topic is centered at "sum" and "sum2". But my question is regarding "result": shouldn't we release result at the end of the method?

Thanks and regards,
luis

Well yes and no: Yes because you do need to release it and No because the 'result' object is pointed to by 'sum2' and as sum = sum2, the 'result' object is released as 'sum' is released.


: Re: Program 7.5 - 7.6 stuck
: bpran August 20, 2011, 07:22:29 AM
I am just making sure that I get this logic correctly.
Please give me some input if I make mistakes.


This is in the Fraction.m file
: (Objective-C)
-(Fraction *) add: (Fraction *) f
{
    Fraction *result = [[Fraction alloc] init];
   
    result.numerator = (numerator * f.denominator) + (denominator * f.numerator);
    result.denominator = denominator * f.denominator;
   
    [result reduce];
    return result;
}

and the other part is in the main.m
: (Objective-C)
    for (i = 1; i <= n; ++i) {  
         [aFraction setTo: 1 over: pow2]; 
         sum2 = [sum add: aFraction]; 
         [sum release]; 
         sum = sum2; 
         pow2 *= 2; 
    } 

let's make example that 'i' in the main.m is 5, so the loop will be 5 times.

The 1st time, method 'add' will create object and put the reference to result and return the reference to sum2.
And then the original sum is destroyed, after that the reference copy from sum2 into sum.

The 2nd time, the method 'add' will create NEW OBJECT at NEW MEMORY LOCATION and the reference store in the result and return the reference into sum2 which replace the previous reference sum2 had.
The [sum release] will destroy the object that created by the method 'add' during the first loop (when i=1), after that sum will get the reference from sum2  (result also pointing at the same object here too).

The point here is the [sum release] from the i=1 and i=2 destroying different thing. One is destroying the object created by the setTo: over: method (the original sum) and the 2nd one is the object created by add method. Am I right here?

This process repeat until it fulfill the 'for' condition and then at the end of main.m we see another [sum release] which will destroy the object which sum, sum2, and result all pointing at the same thing.

Forgive my English, if my post is not clear please let me know, I will try to rephrase the wording.
Thank you and please let me know all your comments.


: Re: Program 7.5 - 7.6 stuck
: bpran August 21, 2011, 09:01:12 PM
I really need someone to give comment on my post above.

Just want to make sure that I get the logic correctly, otherwise no point continuing reading thru.

Thank you.


: Re: Program 7.5 - 7.6 stuck
: Buko December 29, 2011, 04:38:25 AM
Apologies for contributing to an old thread but this problem has taken me all day to figure out and I wanted to share my understanding of it. It was driving me nuts but I didn't want to skip it. I am really glad that I didn't as it has corrected some wrong assumptions that I had made in my head.  It has taken me going through the code over and over and reading all the relevant threads but in the end drawing some diagrams with pen and paper in conjunction (which I always find very helpful) is what solved the mystery for me. At least, I think I have got it right. Any feedback if anyone is still around would be cool.

My main mistake was to think of the variables as the objects themselves rather than pointers that pointed to memory locations where the objects exist. This is why I found the

[sum release];

line in mid-loop really confusing. It didn't make sense to me that you could release it and then immediately on the next line use it again. I now understand that the memory location was released but the pointer is left free to point at elsewhere on the next line.

It was taking too long to draw the diagrams in ASCII so I have included my hand drawn page below.

If the memory locations weren't released in the loop but sum was made to point to the new sum then all those shaded boxes below would add up and all those memory locations would still be in use with no way to release them because the pointer to them would have moved on hence the memory leak. If the for loop was a long one consisting of hundreds or more iterations then that's a lot of shaded boxes being wasted!

I hope this makes sense and is helpful to someone in the future.

(http://farm8.staticflickr.com/7159/6593424957_19f37a8083_b.jpg) (http://www.flickr.com/photos/53054775@N00/6593424957/)
SCN_0001 (http://www.flickr.com/photos/53054775@N00/6593424957/) by Bukoth (http://www.flickr.com/people/53054775@N00/), on Flickr


Sorry, the copyright must be in the template.
Please notify this forum's administrator that this site is missing the copyright message for SMF so they can rectify the situation. Display of copyright is a legal requirement. For more information on this please visit the Simple Machines website.