Amazon.com Widgets Program 7.5 - 7.6 stuck
Welcome, Guest. Please login or register.
Did you miss your activation email?
July 26, 2014, 04:09:53 AM
Home Help Search chat Login Register 
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+ Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+ Old Stuff
| |-+ Chapter Study
| | |-+ Chapter 7 - More on Classes
| | | |-+ Program 7.5 - 7.6 stuck
Pages: [1] 2 3 ... 7 Go Down
Print
Author Topic: Program 7.5 - 7.6 stuck (Read 23167 times)
amuso
Jr. Member
**
Posts: 68


Hope to make a living coding...

amuso@scw.net




on: 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 Smiley

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  Cheesy

Logged

MacBook MB063 4GB OS X 10.7.3 (Xcode 4.3)
iMac MA876 3GB OS X 10.7.3
iPhone 4S 16GB 5.0.1 / iPad 2 16GB 5.0.1
Need translations to Norwegian? Happy to help.
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #1 on: February 12, 2009, 07:11:55 AM

The declaration
Code: (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:

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

A subsequent statement like
Code: (Objective-C)
resultFraction = [[Fraction alloc] init];
will set up the connection between an allocated Fraction object and resultFraction like this:
Code: (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

Code: (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!!)   Grin

Cheers,

Steve
Last Edit: October 05, 2009, 05:04:30 PM by skochan Logged
amuso
Jr. Member
**
Posts: 68


Hope to make a living coding...

amuso@scw.net




Reply #2 on: 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 Smiley

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 Smiley Time for the next chapter. Well, actually I have to do my exercises first.
Logged

MacBook MB063 4GB OS X 10.7.3 (Xcode 4.3)
iMac MA876 3GB OS X 10.7.3
iPhone 4S 16GB 5.0.1 / iPad 2 16GB 5.0.1
Need translations to Norwegian? Happy to help.
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #3 on: 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.  Smiley

Cheers,

Steve
Logged
InRainbows
Newbie
*
Posts: 2






Reply #4 on: 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:

Code: (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!
Logged
esc
Global Moderator
Full Member
*****
Posts: 230






Reply #5 on: 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:

Code: (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).

Logged
mdeh
Full Member
***
Posts: 166






Reply #6 on: 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:

Code: (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.
Last Edit: February 20, 2009, 11:47:04 PM by mdeh Logged
InRainbows
Newbie
*
Posts: 2






Reply #7 on: 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!
Logged
ezrock
Newbie
*
Posts: 10






Reply #8 on: 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):

Code: (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.
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #9 on: 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
Logged
ezrock
Newbie
*
Posts: 10






Reply #10 on: 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.
Logged
demetri007
Newbie
*
Posts: 2


Email




Reply #11 on: March 20, 2009, 07:31:02 PM

Code: (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?
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #12 on: 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
Last Edit: March 20, 2009, 07:58:25 PM by skochan Logged
demetri007
Newbie
*
Posts: 2


Email




Reply #13 on: 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
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #14 on: 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
Logged
Pages: [1] 2 3 ... 7 Go Up
Print
Jump to:



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.