Re: Initializing an Array
Re: Initializing an Array
- Subject: Re: Initializing an Array
- From: Jeff Galyan <email@hidden>
- Date: Tue, 22 Jan 2002 13:30:35 -0700
On 1/22/02 1:11 PM, "Ondra Cada" <email@hidden> wrote:
>
Jeff,
>
>
unimportant parts edited out:
>
>
>>>>>> Jeff Galyan (JG) wrote at Tue, 22 Jan 2002 11:57:56 -0700:
>
JG> @interface AppCrasher : NSObject {
>
JG> NSString *myString;
>
JG> }
>
JG> @end
>
>
JG> @implementation AppCrasher
>
JG> - (id)initWithString:(NSString *)aString
>
JG> {
>
>
if (!(self=[super init]) return nil; // or at the very least "[super init]"!
I was doing exactly that in the real class I was seeing this in.
>
>
JG> myString = [aString copy];
>
JG> [myString retain];
>
>
No need to retain -- would leak
Not retaining resulted in an immediate crash.
>
>
JG> return self;
>
JG> }
>
>
JG> - (NSString *)methodOne
>
JG> {
>
JG> // create a char* and send [myString getCString] with it
>
JG> // do something with the C string
>
JG> // return a new NSString
>
JG> }
>
>
Kinda imprecise. There can be any kind of problem inside, which cause any
>
kind of strange bugs.
Doesn't matter what you do with it here. In my case, I was doing:
char *buffer, *tail;
int aNumber;
[myString getCString:buffer];
aNumber = (int)strtol( buffer, &tail, 0 );
...
>
>
JG> @implementation SomeClass
>
JG> - (void)getCrashed:(NSString *)someString
>
JG> {
>
JG> AppCrasher *myCrasher;
>
JG> NSString *strOne, *strTwo, *strThree, *strFour, *strFive, *strSix;
>
JG>
>
JG> myCrasher = [[AppCrasher alloc] initWithString:someString];
>
>
This again would leak -- you should autorelease it immediately.
Thanks for the pointer (no pun intended). I'll make sure I do that in the
real version of this class.
>
>
Actually, if you really can see mysterious changing of variable contents
>
(like "myString" stopping to contain a decent value and lo! it contains nil
>
for no apparent reason) it looks like you access uninitialized pointers or
>
so, and have bad luck enough that they happen to point to your data instead
>
of some nonsense address which would cause SIGBUS.
Setting a breakpoint in -initWithString: and printing the aString object
showed aString was indeed a valid string. The signal I was getting was
SIGSEGV.
>
>
JG> ....If you step
>
JG> through in the debugger (and remember, this is with optimization turned
>
JG> off), you'll see a new instance of myCrasher get created, then while you
>
JG> step through the calls to you'll see myString get initialized properly,
>
JG> then somewhere between the call to methodFour and methodSix (it varies),
>
JG> myString suddenly becomes nil
>
>
Try NSLog or the ol' plain printf:
>
>
NSLog(@"line %d, myString %x",__LINE__,myString);
Did that too, and after sending -retain to the copied string in
-initWithString: myString claimed to be valid... Until -initWithString:
exited.
>
>
to be sure of the value even for the (*very* unlikely, but possible) case
>
there is some problem of displaying values between gcc and gdb.
>
>
JG> even though myCrasher has not been
>
JG> deallocated yet, so therefore, the ivar myString should not be getting
>
JG> sent a release message.
>
>
First, it would not go nil even if yourCrasher is deallocated -- at least
>
not immediately. Later -- when the place in memory gets reallocated to
>
another object -- it could get any value.
>
>
Besides, not getting release message would never mean crash; the result
>
would be just a leak.
>
---
I know that's how it's *supposed* to work, but that's not how it *is*
working. I've spent two weeks trying to track this down already, and tried
every trick in the book to find what I was doing wrong (I even tried
deliberately leaking it by sending it multiple retain messages and not
releasing it in -dealloc). Unfortunately, nothing has helped.
--Jeff