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







Reply #75 on: March 05, 2010, 03:10:44 PM

Quote
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

Logged
macgruder
Newbie
*
Posts: 1






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


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

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







Reply #77 on: 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 
Logged
marks
Newbie
*
Posts: 12






Reply #78 on: 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
Code: (Objective-C)
Fraction *result = [[Fraction alloc] init]; 

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

Thanks,
Mark
Last Edit: April 25, 2010, 09:13:10 AM by marks Logged
marks
Newbie
*
Posts: 12






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







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






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

Code: (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;
}
Last Edit: June 13, 2010, 10:07:23 PM by Jack Logged
anmldr
Jr. Member
**
Posts: 53






Reply #82 on: 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
Last Edit: January 01, 2011, 07:40:10 PM by anmldr Logged
chuckbo
Newbie
*
Posts: 1






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







Reply #84 on: 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
Logged
ZimBob
Newbie
*
Posts: 5


Email




Reply #85 on: 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
Logged
jcd
Newbie
*
Posts: 5






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







Reply #87 on: 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
Logged
jcd
Newbie
*
Posts: 5






Reply #88 on: 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
Logged
Luis.Z
Newbie
*
Posts: 1


Email




Reply #89 on: 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
Logged
Pages: 1 ... 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.