• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Memory Management
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Memory Management


  • Subject: Re: Memory Management
  • From: Nat! <email@hidden>
  • Date: Fri, 10 Aug 2001 23:07:52 +0200

Am Mittwoch, 8. August 2001 um 20:05 schrieb Robert Thompson:

> ----- Original Message -----
> From: "Nat!" <email@hidden>
>> //
>> // (gdb) Starting program: /Network/Users/nat/src/test/test
>> // [Switching to process 759 thread 0x2600]
>> // Aug 08 02:05:00 test[759] 0 : <SonOfJekyll: 0x4ebf8> = 660
>> // Aug 08 02:05:00 test[759] 1 : <SonOfJekyll: 0x4ebf8> = 665
>> // Aug 08 02:05:00 test[759] 2 : <SonOfJekyll: 0x51050> = 664
>> // Aug 08 02:05:00 test[759] 3 : <SonOfJekyll: 0x51050> = 661
>> // Aug 08 02:05:00 test[759] 4 : <SonOfJekyll: 0x51050> = 664
>> // Aug 08 02:05:00 test[759] 5 : <SonOfJekyll: 0x51050> = 669
>> // Aug 08 02:05:00 test[759] 6 : <SonOfJekyll: 0x51050> = 662
>> // Aug 08 02:05:00 test[759] 7 : <SonOfJekyll: 0x51050> = 665
>> //
>> // Program received signal SIGSEGV, Segmentation fault.
>> //
>>
> Ummm... when I run the program (on Mac OS X 10.0.4), I get this:
> Aug 08 13:58:47 jekyll[11625] 0 : <SonOfJekyll: 0x914a0> = 660
> Aug 08 13:58:47 jekyll[11625] 1 : <SonOfJekyll: 0x914a0> = 665
> Aug 08 13:58:47 jekyll[11625] 2 : <SonOfJekyll: 0x914a0> = 664
> Aug 08 13:58:47 jekyll[11625] 3 : <SonOfJekyll: 0x914a0> = 661
> Aug 08 13:58:47 jekyll[11625] 4 : <SonOfJekyll: 0x914a0> = 664
> Aug 08 13:58:47 jekyll[11625] 5 : <SonOfJekyll: 0x914a0> = 669
> Aug 08 13:58:47 jekyll[11625] 6 : <SonOfJekyll: 0x914a0> = 662
> Aug 08 13:58:47 jekyll[11625] 7 : <SonOfJekyll: 0x914a0> = 665
> Aug 08 13:58:47 jekyll[11625] 8 : <Hyde: 0x975f0> = 666
> Aug 08 13:58:47 jekyll[11625] 9 : <SonOfJekyll: 0x914a0> = 667
> Aug 08 13:58:47 jekyll[11625] 10 : <SonOfJekyll: 0x914a0> = 668
> Aug 08 13:58:47 jekyll[11625] 11 : <SonOfJekyll: 0x914a0> = 661
> Aug 08 13:58:47 jekyll[11625] 12 : <Hyde: 0x975f0> = 666
> Aug 08 13:58:47 jekyll[11625] 13 : <SonOfJekyll: 0x914a0> = 661
> .... and so on up to 100 lines
>
> Interestingly, though, if I add a method to print comment when
> amIEvil ==
> 666, I get
> Aug 08 14:04:23 jekyll[11765] 0 : <SonOfJekyll: 0x91490> = 660
> Aug 08 14:04:23 jekyll[11765] 1 : <SonOfJekyll: 0x91490> = 665
> Aug 08 14:04:23 jekyll[11765] 2 : <SonOfJekyll: 0x91490> = 664
> Aug 08 14:04:23 jekyll[11765] 3 : <SonOfJekyll: 0x91490> = 661
> Aug 08 14:04:23 jekyll[11765] 4 : <SonOfJekyll: 0x91490> = 664
> Aug 08 14:04:23 jekyll[11765] 5 : <SonOfJekyll: 0x91490> = 669
> Aug 08 14:04:23 jekyll[11765] 6 : <SonOfJekyll: 0x91490> = 662
> Aug 08 14:04:23 jekyll[11765] 7 : <SonOfJekyll: 0x91490> = 665
> Aug 8 14:04:23 jekyll[11765] Got nil as the string argument in
> NSMutableString. Pass empty string instead. Will probably crash.
> Bus error
>

Hey I guess then there's no problem there at all :)

But seriously, though... You can probably reproduce the crash on your
machine if you increase the number of XXXs in the initWithComment call.

Here is a little background info as to why it crashes, in case that
isn't obvious.

The problem is that the original initWithValue: of Jekyll may return an
object of type Hyde instead of the object called on. Now Hyde is about 8
bytes large. 4 bytes for the isa pointer and 4 bytes for the integer
(and then maybe some padding). (check http://www.mulle-
kybernetik.com/opti-2.html for a short intro into object memory layout)

@interface Jekyll : NSObject
{
int amIEvil;
}

@interface Hyde : Jekyll
{
}
@end

The subclass SonOfJekyll is 1024 bytes longer.

@interface SonOfJekyll : Jekyll
{
char comment[ 1024]; // so our subclass does need some more
ivar space...
}

The problem arises when in the SonOfJekyll we write the method like this

- (id) initWithComment:(char *) s
{
// blessed are the meek for they shall inherit ...
if( (self = [super initWithValue:rand() % 10 + 660]) == nil)
return( self);

strncpy( comment, s, sizeof( comment));
return( self);
}

because if we get a Hyde object back we only have room for 8 bytes and
the strncpy will clobber memory which is not ours. If we get a regular
SonOfJekyll object back (the one we called super initWithValue: on),
everything's fine.

This learns us that

if( (self = [super init...]) != nil)
{
}

only handles the nil case properly, and maybe a few cases where the
returned object is not the same as previous self and the size of the
objects are the same (HIGHLY unlikely), in this sense I find the
"self = " is misleading, for those (Mike) who didn't get it.

It is still my opinion that you should not blindly code init methods
but... enough of this.

Nat!


References: 
 >Re: Memory Management (From: "Robert Thompson" <email@hidden>)

  • Prev by Date: Undo in formatted text fields
  • Next by Date: NSUserDefaults
  • Previous by thread: Re: Memory Management
  • Next by thread: Oddity
  • Index(es):
    • Date
    • Thread