Amazon.com Widgets Program 7.5 - 7.6 stuck
Welcome, Guest. Please login or register.
Did you miss your activation email?
October 31, 2014, 10:07:07 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] 4 5 ... 7 Go Down
Print
Author Topic: Program 7.5 - 7.6 stuck (Read 24039 times)
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #30 on: 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
Logged
ariel_mirahy
Newbie
*
Posts: 11


Email




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

Last Edit: April 11, 2009, 05:15:46 PM by ariel_mirahy Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #32 on: 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
Logged
ariel_mirahy
Newbie
*
Posts: 11


Email




Reply #33 on: 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!  Grin
Logged
ariel_mirahy
Newbie
*
Posts: 11


Email




Reply #34 on: 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!  Grin

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:

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

Code: (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'?
Last Edit: April 12, 2009, 12:02:26 AM by ariel_mirahy Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #35 on: 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.
Last Edit: April 12, 2009, 11:11:29 AM by skochan Logged
ariel_mirahy
Newbie
*
Posts: 11


Email




Reply #36 on: 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!
Last Edit: April 12, 2009, 11:09:16 AM by ariel_mirahy Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #37 on: April 12, 2009, 11:26:55 AM

Let's look at the three key statements in the loop one at a time:

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

Cheers,

Steve




The diagram would be similar to the one at the top of this thread.
Logged
ariel_mirahy
Newbie
*
Posts: 11


Email




Reply #38 on: 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!.
Last Edit: April 12, 2009, 12:35:08 PM by ariel_mirahy Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #39 on: April 12, 2009, 12:57:45 PM

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

Gee, thanks!  Shocked

Steve
Logged
ARMIZZZ
Newbie
*
Posts: 1


Email




Reply #40 on: April 12, 2009, 02:11:34 PM

Let's look at the three key statements in the loop one at a time:

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

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...
Last Edit: April 12, 2009, 02:15:28 PM by ARMIZZZ Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #41 on: 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
Last Edit: April 12, 2009, 02:23:31 PM by skochan Logged
MarkReid
Full Member
***
Posts: 173






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







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

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

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






Reply #44 on: 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?
Logged
Pages: 1 2 [3] 4 5 ... 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.