Hi Ben,
You say the crash occurs in this line:
individuals[individualCount++] = individualsForPop[i];
The problem may be in the post-increment (individualCount++). IIRC,
there is no agreed-upon compiler standard as to whether the post-
increment will occur before or after the assignment. It is possible
that you're using the bytes after the end of the array as a pointer,
which points to a random location rather than to your desired data.
If you want the increment to happen after the assignment, do this:
for (i = 0; i < individualCountForPop; ++i) {
individuals[individualCount] = individualsForPop[i];
individualCount++;
}
If you want it before, just reverse the order of the two lines.
I've had many a headache in the past with things like this!!
Soong
----- Original Message ----
From: Ben Haller <email@hidden>
To: Greg Parker <email@hidden>
Cc: Cocoa List <email@hidden>
Sent: Thu, October 15, 2009 4:44:23 PM
Subject: Re: GC crash due to being naughty
On 15-Oct-09, at 7:30 PM, Greg Parker wrote:
A pointer value stored in an ordinary malloc block is neither a
"strong" nor a "weak" reference. It is a dangling pointer. It can
be used safely, but requires great care because the garbage
collector has no knowledge of what you're doing.
The auto_zone_root_write_barrier() crash can occur when you take
the address of a global variable, then store into the global
indirectly via that address. What does the crashed line of code
look like?
OK, here's a bit of context. The backtrace:
#0 0x95058d7b in auto_zone_root_write_barrier ()
#1 0x964e40a8 in objc_assign_strongCast_gc ()
#2 0x00007198 in -[AKPopulation addIndividualsFromPopulation:]
(self=0x102b740, _cmd=0xe76c, population=0x10a9250) at .../
AKPopulation.m:101
That method:
- (void)addIndividualsFromPopulation:(AKPopulation *)population
{
UInt32 individualCountForPop = [population individualCount];
AKIndividual **individualsForPop = [population individuals];
int i;
if (individualCount + individualCountForPop > individualCapacity)
{
individualCapacity = (individualCount +
individualCountForPop) * 2;
individuals = realloc(individuals, individualCapacity * sizeof
(AKIndividual *));
}
for (i = 0; i < individualCountForPop; ++i)
individuals[individualCount++] = individualsForPop[i];
}
The crash is in the last line of the method, in the assignment.
The class as it stands right now:
@interface AKPopulation : NSObject
{
NSString *title;
UInt32 individualCount;
UInt32 individualCapacity;
AKIndividual **individuals; // malloc'ed array of
AKIndividual *
}
@property (readwrite, copy) NSString *title;
@property (readonly) UInt32 individualCount;
@property (readonly) AKIndividual **individuals;
...
@end
So the intent of the method is just to bulk-add individuals from
one population into another population.
Perhaps another way to ask the question is: suppose you wanted to
implement a new collection class, akin to NSMutableArray but somehow
different. How would you safely do it under GC, without using any
of the pre-made Cocoa collections internally? That's all my
AKPopulation really is: a poor man's (but a speedy man's!) re-
implementation of something like NSMutableArray. Ought to be
possible, right? So how do I manage this write barrier business to
make it work properly?
Ben Haller
Stick Software
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden