I have an ivar, keys which is an NSMutableArray containing 50 strings. When my view loads, i am getting a zombie messaged error in Instruments, and it is directing me to this line of code:
for (int row = 0; row < r; row++) {
for (int column = 0; column < c; column++){
otherArray[column][row] = [[[keys objectAtIndex:0] retain] autorelease];
//^ Instruments brings me here
[keys removeObjectAtIndex:0];
}
}
I have retained the value to keep it alive so that the remove will not cause a crash, but it still does. I have tried not retaining, and autoreleasing and it still crashes. This method of retaining and autoreleasing works when i have a local variable, but not an ivar...
I need an ivar because i need to access the strings elsewhere.
Thanks
synthesize it and release and it in your dealloc.
Solved -- Memory management problem - keys was not being correctly retained.
Related
I'm handling RemoteIO to get mic inputs and modify them little.
Sometimes it crashes with EXC_BAD_ACCESS and there is no more message.
The lines that make crashes are these;
int currPower = [[powers objectAtIndex:i] intValue];
int prevPower = [[powers objectAtIndex:i - 1] intValue];
explaining the code,
"powers" is NSMutableArray.
[powers count] was always bigger than variable "i"
Struggling for a while, I found a good way to fix it.
A environment variables.
So I set NSZombieEnabled and also NSDebugEnabled so that I could see the reason of the crashes.
But even though I set the variables, Xcode shows no message.
(But it correctly shows messages when a crash occurs from other line.)
Also a weird thing is that it doesn't crash just after the start of run;
it crashes in a minute in average. (But the times really varied.)
And this is a little guess. When I decreased the rate to half than before,
it was more stable.
So, is it a problem with NSMutableArray, because NSMutableArray method couldn't catch up the speed of the rate?
or do you see some other possible reasons?
=========================================================================================
There are some more codes.
I allocated powers in this way..
powers = [[NSMutableArray alloc] initWithCapacity:POWER_ARRAY_SIZE];
where I release the powers array is..
- (void)dealloc {
[powers release];
[super dealloc];
}
and no where else.
more detailed code is this.
- (void)drawRect:(CGRect)rect
{
...//Do Something
...//Check "endindex" and "startindex" not to exceed boundary
for (int i = endindex; i > startindex; i-=1)
{
int currPower = [[powers objectAtIndex:i] intValue];
int prevPower = [[powers objectAtIndex:i - 1] intValue];
...//Doing something
}
}
this drawRect: method is calling from Main Thread(By Timer) in every millisecond.
--
updating(more specifically adding) powers in this method
- (void)setPower:(int)p
{
[powers addObject:[NSNumber numberWithInt:p]];
while ([powers count] > POWER_ARRAY_SIZE){
[powers removeObjectAtIndex:0];
}
}
and also this method is calling in every millisecond.
and this is calling in background thread.
so without #autoreleasepool XCode Shows message of alert of leaking
for this reason I blocked the method(setPower) with #autoreleasepool{..}
If NSZombies solved your problem it means that your NSMutableArray is being released somewhere, or it's in an autorelease pool. Also you could be trying to write outside the bounds of your array.
If the NSMutableArray is in an autorelease pool (it was created by a convenience method or you explicitly autoreleased it) manually retain it and release it when you no longer need it.
If the object is not in an autorelease pool check when the release is called for that object.
Write a simple warning before the assignment:
if( i <= 0 || i >= [powers count] ) NSLog(#"Here's the problem. i = %d", i);
I found the answer.
Crashes are occurred because NSMutableArray of objected-C sometimes ack wrong.
That's when I try to do something in every milliseconds with it.
So I changed the Objective-C array to C array, like
int power[ARRAYSIZE];
and after I changed it, it works fine.
May be NSMutableArray isn't that light to do something really fast.
Hi I have a lot of problems to remove the objects of my mutable array.
I have a method which send back a mutable initialized with a custom object.
This mutable is declared like autorelease for releasing after method.
In my return, I retain the mutable to not loose it.
I want in this second method to remove the content of my mutable and release my mutable.
But my app quit and fail.
//first method which return my mutable
NSMutableArray *highScores = [[[NSMutableArray alloc] init]autorelease] ;
for (....)
{
HighScore *currentHighScore = [[HighScore alloc] init];
currentHighScore.user = name;
currentHighScore.score = score;
//add to the array
[highScores addObject:currentHighScore];
[currentHighScore release];
}
return highScores;
// method which use the first method
//retrieve with retain to keep.
highScoreList = [[HighScoreViewController getHighScores:NormalGameModeXML]retain] ;
HighScore *currentHighScore;
int count = [highScoreList count];
for (int i = 0; i < count ; i++)
{
currentHighScore = [highScoreList objectAtIndex:i];
}
This is working, but off course I have memory leak for all the objects in the mutable not released.
But if i'm trying to release the object of the mutable and the mutable itself by this :
//remove Mutable array content.
//[highScoreList removeAllObjects] ;
//[highScoreList release];
My app is quitting.
Do you have a solution to avoid the memory leak and clean it well?
Try using NSZombieEnabled to check the reason for an EXC_BAD_ACCESS..
HowTo is found here..
//[highScoreList removeAllObjects] ;
//[highScoreList release];
No need to removeAllObjects prior to release.
Note that if you use highScoreList after it is deallocated, your app will crash as you describe. I.e. if you use highScoreList after the above, BOOM.
You could set highScoreList to nil, but a better solution is to understand why you are using an object after you think you should be done with it.
And, as always:
If there is a crash, there is a backtrace. Post it.
OK, This is a method from my program that keeps giving the EXC_BAD_ACCESS error and crashing. I indicated the line below. questionsShown is a readwrite property and points to an NSMutableArray that I initialize with a capacity of 99 at an earlier point in the program. When I debug everything appears normal in terms of the property being allocated. I assumed there must be some issue with memory management but I am having serious trouble finding the problem. Thanks in advance for any help.
#synthesize questionList;
#synthesize questionLabel;
#synthesize questionsShown;
-(IBAction)next{
int numElements = [questionList count];
int r;
if (myCount == numElements){
[questionLabel setText:#"You have seen all the questions, click next again to continue anyways."];
[questionsShown release];
questionsShown = [[NSMutableArray alloc] initWithCapacity:99];
myCount = 0;
}
else {
do {
r = rand() % numElements;
} while ([questionsShown indexOfObjectIdenticalTo:r] != NSNotFound);
NSString *myString = [questionList objectAtIndex:(NSUInteger)r];
[questionLabel setText:myString];
myCount++;
[questionsShown addObject:r]; //results in crash with message EXC_BAD_ACCESS
myCount++;
}
}
The EXC_BAD_ACCESS is coming from dereferencing r, which is just an integer. Your compiler should be giving you a warning (make pointer from integer without a cast) on that line.
If questionsShown is supposed to be some kind of index set for you (which it appears to be), you might want to either use that class, or you will have to box your integer in an NSNumber object. So:
[questionsShown addObject:[NSNumber numberWithInt:r]];
and when you read it:
[questionsShown indexOfObjectIdenticalTo:[NSNumber numberWithInt:r]]
I recommend, however, that you take a look at the NSIndexSet documentation.
With a mutable index set, you could do:
[questionsShownIndexSet containsIndex:r]
and
[questionsShownIndexSet addIndex:r]
i have a problem.
When i compile my program there isn't a error but, when i start it these retern with “EXC_BAD_ACCESS”.
I looking for the error with the debug and i find it in these method but i don't understand where...
PS:the program enters in the loop sometimes.
-(void)updateMinPosition{
float valueMinX = 150;
float valueMinY = 150;
float valueMinZ = 150;
NSString *nameMinimoX = [NSString stringWithFormat:#"default"];
NSString *nameMinimoY = [NSString stringWithFormat:#"default"];
NSString *nameMinimoZ = [NSString stringWithFormat:#"default"];
for(int i = 0; i< [arrayPosizioniMovimento count]; i++){
//Posizione is my class. It contain a NSString name, 3 float valueX, valueY, valueZ
Posizione *tempPosition;
tempPosition = [[Posizione alloc]init];
tempPosition = [arrayPosizioniMovimento objectAtIndex:i];
if(tempPosition.valueX <= valueMinX){
valueMinX = tempPosition.valueX;
nameMinimoX = tempPosition.nome;
}
if(tempPosition.valueY <= valueMinY){
valueMinY = tempPosition.valueY;
nameMinimoY = tempPosition.nome;
}
if(tempPosition.valueZ <= valueMinZ){
valueMinZ = tempPosition.valueZ;
nameMinimoZ = tempPosition.nome;
}
[tempPosition dealloc];
}
labelMinX.text = nameMinimoX;
labelMinY.text = nameMinimoY;
labelMinZ.text = nameMinimoZ;
}
For the 1st glance there're several problems with your code:
Posizione *tempPosition;
tempPosition = [[Posizione alloc]init];
tempPosition = [arrayPosizioniMovimento objectAtIndex:i];
Here in the second line you create new Posizione instance and right after that assign another value to the same variable. In effect that will mean that your created instance will be never used and cause memory leak. To use element from array just write
Posizione *tempPosition = [arrayPosizioniMovimento objectAtIndex:i];
The second one - is the following line
[tempPosition dealloc];
First of all you should never call this method directly but rather send an object -release message - it will be deallocated automatically when its retain count becomes 0. In your case you do not retain tempPosition object in that code so there;s no need to release it here - just remove that line.
P.S. Using fast enumeration can also make your code more readable and less error prone:
for (Posizione *tempPosition in arrayPosizioniMovimento){
if(tempPosition.valueX <= valueMinX){
...
It looks like it may be the [tempPosition dealloc] call. You're declaring that variable and doing an alloc/init on it but then just assigning it to the object within the array, so the alloc/init is unneeded. When you make the call to dealloc at the bottom you're releasing that object that resides in the array, so your array will now have a null value which will cause the EXEC.... error
You can enable Objective-C Exception breakpoints to pinpoint the line.
On thing that jumps out is
[tempPosition dealloc];
I'm not sure what to tell you to do. You need to call release not dealloc.
[tempPosition release];
But im not sure how that fits into the rest of your code, where you are allocating a variable then immediately assigning it another value.
I think you should just remove the alloc and dealloc
so delete:
//Posizione is my class. It contain a NSString name, 3 float valueX, valueY, valueZ
Posizione *tempPosition;
tempPosition = [[Posizione alloc]init];
and
[tempPosition dealloc];
Pease show how do you initialize arrayPosizioniMovimento.
If you initialized it like arrayPosizioniMovimento = [NSMutableArray arrayWithCapacity:n]; than you'll need to add [arrayPosizioniMovimento retain];
ok. I have a really odd and mind boggling problem. I have two class files, both of which are NSObject inheritors. The series of code is as follows
CustomClass *obj;
obj = [[CustomClass alloc] init];
[myArray addObject:obj]; <--------Immediately after this line if I hover over the array it shows it as having 1 object that is out of scope.
If I hover over both objects they both have what look to be initialized memory locations so I really have no idea what is going on here. Thanks in advance.
UPDATE: There is a place in the code where I call a function repeatedly with a timer. Inside of the timer I do the following.
CustomClass *obj = [CustomClass alloc];
obj = [myArray objectAtIndex:0];
obj.var += 10;
[obj release];
On the line obj.var I get a EXC_BAD_ACCESS error. I am probably doing the alloc and releases incorrectly considering it is called repeatedly but I have tried everything I can think of.
I think you are referring to the XCode debugging feature which shows you the content of variables.
I did encounter the same issue as well, and what I'm sure of is that this is generally not a problem with your code.
Now what I'm not sure of is why this happens, but I believe that the variable obj in your example is not used after the call anymore. This means the compiler reuses the place where this reference was stored, thus the debugger could "lose" the pointer to your variable and it will appear as out of scope (but I am no expert in the ways of gcc or the debugger, so I could be wrong here).
This code is wrong:
CustomClass *obj = [CustomClass alloc];
obj = [myArray objectAtIndex:0];
obj.var += 10; [obj release];
What you are doing is allocing a new CustomClass (without initializing it, which should never be done), then replacing it with the object from the array (leaking the old one), and then afterwards releasing the object from the array. This will cause a crash the next time the object in the array is accessed. Instead, just say:
CustomClass *obj = [myArray objectAtIndex:0];
obj.var += 10;
Don't release unless you retain in advance. (See the Cocoa memory management guide for more information).
This isn't the problem you are referring to, but please don't do this:
CustomClass *obj = [CustomClass alloc];
Never issue an alloc without an init of some sort. Also, in the context of the code you posted it isn't required, as you assign a value to obj on the next line.
Then [obj release]; isn't required, as you haven't retained the obj value you obtain from myArray. You are probably doing it because of the preceding alloc, which as I have said isn't required.
if a reference to obj.var is causing a BAD_ACCESS, then either obj or var has been dealloced by code elsewhere, almost certainly var.