Amazon.com Widgets Program 7.5 - 7.6 stuck
Welcome, Guest. Please login or register.
Did you miss your activation email?
June 19, 2013, 03:04:39 PM
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 [4] 5 6 7   Go Down
Print
Author Topic: Program 7.5 - 7.6 stuck  (Read 17494 times)
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #45 on: April 14, 2009, 07:19:41 AM »

Quote
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

Logged
MarkReid
Full Member
***
Posts: 173






« Reply #46 on: 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.
Logged
MarkReid
Full Member
***
Posts: 173






« Reply #47 on: 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.
« Last Edit: April 15, 2009, 08:08:40 AM by MarkReid » Logged
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #48 on: 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
Logged
MarkReid
Full Member
***
Posts: 173






« Reply #49 on: 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.
Logged
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #50 on: 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.

Quote
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
Logged
MarkReid
Full Member
***
Posts: 173






« Reply #51 on: 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.  Smiley
Logged
MrTech40
Newbie
*
Posts: 4






« Reply #52 on: 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!! Wink

Robert



Logged
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #53 on: 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
Logged
MrTech40
Newbie
*
Posts: 4






« Reply #54 on: 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
Logged
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #55 on: 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
Logged
MrTech40
Newbie
*
Posts: 4






« Reply #56 on: 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
« Last Edit: May 02, 2009, 04:41:47 PM by MrTech40 » Logged
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #57 on: May 02, 2009, 04:50:07 PM »

Quote
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.   Smiley Smiley

Steve

Logged
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #58 on: May 02, 2009, 05:16:56 PM »

Quote
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

Quote
----------                                 ----------
|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.

Quote
----------                                 ---------------------------
| 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.


Quote
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.
                                                                                                                         ---------
Quote
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.                                                                   ---------   
                 ---------                                                                                                           
Quote
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:

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

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

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

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

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

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



« Last Edit: May 02, 2009, 05:22:00 PM by skochan » Logged
MrTech40
Newbie
*
Posts: 4






« Reply #59 on: May 02, 2009, 06:51:48 PM »

Everything is crystal clear now!! Smiley  Wink  Cheesy  Grin  Cool

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

Robert
Logged
Pages: 1 2 3 [4] 5 6 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.