error “EXC_BAD_ACCESS” in my program - iphone

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];

Related

objective c perform selector in background and autoreleasepool

I am developing an iphone application which has some data stored in a sqllite database. When my view loads i would like to load the data from the database on a background thread. The problem is the application keeps crashing and i dont know why.
The code:
-(id) init
{
if((self=[super init]))
{
[self performSelectorInBackground:#selector(loadList) withObject:nil];
}
}
-(void) loadList
{
#autoreleasepool
{
Loader * loader = [[Loader alloc] init];
NSMutableArray * array = [loader getItemList];
[array retain];
NSLog(#"Got %d items",[array count]);
[self performSelectorOnMainThread:#selector(createList:) withObject:array waitUntilDone:false];
[loader release];
}
}
-(void) createList: (NSMutableArray*) array
{
items = array;
int i;
Item * it;
for(i = 0; i < [items count]; i++)
{
it = [items objectAtIndex: i];
[it getName]; // crashes
// populate the list
}
}
Loader returns a NSMutableArray with Item objects. The application crashes when i call the item getName (which returns a NSString*). From what i understand it crashes because the item name properties is being released. What am i doing wrong?
Thanks!
It's likely to be a problem with whatever type of object you're using to populate array.
I'm unable to find finger-on-paper proof but I'm confident that performSelectorOnMainThread:withObject:waitUntilDone: retains its object. However if each of the items in array keeps a reference to loader then they need to take responsibility for retaining that object. It looks like you're attempting to keep it alive manually but — as Chuck alludes to — your call to performSelector... will return instantly and not wait for the call you've made to complete.
This particular bug appears to be that you're passing waitUntilDone:NO, so the array is being released immediately and consequently so are its items.
But in general, UIKit is not thread-safe, so this is just a touchy design. I would probably put the loading of this stuff in another class that handles the task for you instead of right in the view.
I'd put a breakpoint on the line:
it = [items objectAtIndex: i];
Then type
po it
in the debugger, and see what's in the name field. As a guess, I'd say one of two things: 1) the field that getName returns isn't initialized with an object (i.e. isn't a real NSString *) or that you're getting a C string from SQLite (which is what it usually returns) and you're trying to treat it as an NSString *. If it's the latter you can use [myCString stringWithUTF8String] to convert the C string into an NSString *

Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1

I'm getting a memory leak when I`m trying to reset a table view, I thought I could just put release before, but this doesn't help.
What do I need to do here ?
-(void) resetTable{
recordOffset = 10;
rOFactor = 0;
booShowMoreCell = false;
self.transactionsArray = [[NSMutableArray alloc] init]; // leak here
}
Assuming that transactionsArray is a retained property, the problem you are having is that the NSMutableArray is being retained twice.
When you set a retained property it releases the old value, and retains the new (incoming) value. The alloc method also retains the object.
So
// \/--- retain count = 2 \/-- retain count = 1
self.transactionsArray = [[NSMutableArray alloc] init];
The shortest way to resolve this is autorelease the NSMutableArray:
self.transactionsArray = [[[NSMutableArray alloc] init] autorelease];
There's a convenience method way for the above line:
self.transactionsArray = [NSMutableArray array];
As I can't see a [tableView release]-call in this code, that's what's missing - you aren't releasing the tableView before allocating a new one on top of it. That means you're adding a retain count, without removing one first. Adding the release will fix the leak.
On the first sight I would say that you just overwrite the pointer with a reference to a new object and forgetting the old reference which points to an object that was not released yet. As long as you do not use ARC you should use
[self.transactionsArray release]; // Be sure it was alloced before
self.transactionsArray = [[NSMutableArray alloc] init];

Pass variable by reference to method (Objective-C Iphone SDK)

Hi :) This is messing me up quite the bit...
Say I have this method:
-(void) initEvent:(NSMutableArray*) Day day:(float)DayNum
{
//[Day addObject:[[[LifeEvent alloc] init] initVars:100]];
[Day addObject:#"Hello"];
[Day addObject:#"there :)"];
}
I call that method in a small loop:
for (int i = 0; i < 7; i++)
{
NSMutableArray * DayTMP = [[NSMutableArray alloc] init];
[self initEvent:DayTMP day:i];
}
Theoretically, this should pass DayTMP to the function, and add data to that variable. Not the case, instead, it creates a copy of DayTMP, adds data to that value, and drops it. DayTMP never gets modified!
I need to know how to pass values to functions as pointers, not copies, so that DayTMP is modified.
Actually what you are doing here is that you are creating 7 NSMutableArray type objects and the same variable name DayTMP is used for all of them ....... so loose the access of all 6 of them and and you only can access the last one because in every itteration of the loop DayTMP is pointing to new location ....... so to achieve what you want you should do following...
NSMutableArray * DayTMP = [[NSMutableArray alloc] init];
for (int i = 0; i < 7; i++)
{
[self initEvent:DayTMP day:i];
}
Normally your code should work fine except that you never release DayTMP creating a memory leak. You are indeed passing a pointer to an NSMutableArray : (NSMutableArray*).
You "init" DayTMP inside the loop!!!
that means you create (and never release!) the same object many time, overriding it every time, so you kill the old one each time, and you get just the last one: it's a memory error

EXC_BAD_ACCESS in iPhone app - memory management issue

For reference, I've already read:
memory management question -- releasing an object which has to be returned
iPhone: Return NSMutableArray in method while still releasing
Releasing objects returned by method
Which I thought would help :).
This app is a teaching tool and is intended to help people visualize simple genetics. Just some background so the variable names and stuff will make sense. Here's the main code that executes when the app runs:
- (void)viewDidAppear:(BOOL)animated {
ThingzCore *core = [[ThingzCore alloc] init];
ThingzThing *thing1 = [[ThingzThing alloc] init];
thing1.breed = #"AB";
thing1.pattern = #"AC";
thing1.color = #"CA";
thing1.gender = #"XY";
thing1.generation = 1;
thing1.isEgg = NO;
ThingzThing *thing2 = [[ThingzThing alloc] init];
thing2.breed = #"CD";
thing2.pattern = #"BA";
thing2.color = #"CB";
thing2.gender = #"XX";
thing2.generation = 1;
thing2.isEgg = NO;
NSLog(#"Breeding GD BR PT CL G");
ThingzThing *child = [core mateFather:thing1 withMother:thing2];
NSLog(#"Round 1: %# %# %# %# %d",child.gender,child.breed,child.pattern,child.color,child.generation);
sleep(10);
child = [core mateFather:thing1 withMother:thing2];
NSLog(#"Round 2: %# %# %# %# %d",child.gender,child.breed,child.pattern,child.color,child.generation);
sleep(10);
child = [core mateFather:thing1 withMother:thing2];
NSLog(#"Round 3: %# %# %# %# %d",child.gender,child.breed,child.pattern,child.color,child.generation);
sleep(10);
child = [core mateFather:thing1 withMother:thing2];
NSLog(#"Round 4: %# %# %# %# %d",child.gender,child.breed,child.pattern,child.color,child.generation);
sleep(10);
[thing1 release];
[thing2 release];
[core release];
}
And here's what happens when I run it in various ways:
Running without breakpoints, it crashes, with no console message, after the 2nd sleep() but before the "Round 3" NSLog.
Running with breakpoints enabled, but none defined, it runs through the entire sequence. After the fourth sleep(), it crashes with EXC_BAD_ACCESS.
Running with breakpoints enabled and NSZombiesEnabled, it does the same thing as above - no further information, just EXC_BAD_ACCESS.
Running in Instruments, no leaks are shown.
This is the routine being called four times:
-(ThingzThing *)mateFather:(ThingzThing *)father
withMother:(ThingzThing *)mother {
// will we be doing a mutation?
int mutationPercentage = father.generation + mother.generation;
int mutationNumber = (arc4random() % ((unsigned)100 + 1));
BOOL isMutation = NO;
if (mutationNumber <= mutationPercentage) {
isMutation = YES;
}
// get possibilities
NSArray *possibilities = [self possibilitiesByMatingFather:father
withMother:mother
mutations:isMutation];
// randomly select one of the possibilities
int keeping = (arc4random() % ((unsigned)[possibilities count]));
return [possibilities objectAtIndex:keeping];
}
Without pasting in the ENTIRE code, the possibilitiesByMatingFather:withMother:mutations function is returning an NSMutableArray. That routine declares the array by using:
NSMutableArray *possibilities = [NSMutableArray array];
It then:
return possibilities;
It does not send a release or autorelease message to possibilities; my understanding is that creating the array the way I have is an implicit autorelease. I didn't want to alloc the array, because I'm returning it, so wouldn't have the opportunity to explicitly release it.
The objects held in the possibilities NSMutableArray are of a custom class. They are added as follows:
ThingzThing *newThing = [[ThingzThing alloc] init];
newThing.breed = choiceBreed;
newThing.gender = choiceGender;
newThing.color = choiceColor;
newThing.pattern = choicePattern;
newThing.generation = mother.generation + father.generation;
newThing.name = #"";
newThing.isEgg = YES;
[possibilities addObject:newThing];
[newThing release];
Which seems to work most of the time. At least, when breakpoints are enabled, the program runs through the code without complaint until the end, as noted above.
Any suggestions on what I'm doing wrong, here? It's obviously memory management issues of some kind, but I can't sort it in my head.
BTW, in a vain, throwing-things-at-the-wall attempt to figure it out, I did modify the one line from the main routine as follows:
// get possibilities
NSArray *possibilities = [[self possibilitiesByMatingFather:father
withMother:mother
mutations:isMutation] retain];
To no avail. Same results. So the problem isn't in retaining the array returned by possibilitiesByMatingFather:withMother:mutations. Forcing a retain on that return isn't helping.
Frequently in this type of situation, the actual error is not at the location shown in the debugger when the app halts.
For example, the debugger may be pointing to a method call, but the problem actually occurs inside the method -- not when the method is called.
To track things down, I would suggest setting a breakpoint just before the method call that triggers the error -- in your case, this would be the mateFather: withMother: call. Then step into that method. There is a good chance you will find that the problem happens inside that method -- or even inside a method called from within that method.
Check you have the correct property declarations of the string properties of class ThingzThing.
e.g.
#property (nonatomic, retain) NSString* breed;
NEED to be retain or copy NOT assign...
Found it. Buried eight method calls down, I was sending release to an NSArray that was obviously autoreleasing. When the initial calling routine (viewDidAppear) fell down into autorelease mode, it tried to autorelease the already-released object, and exploded. Good grief - is there any way XCode could have helped me track that down?
In any event, in case anyone runs across this, make bloody sure you're not sending a release message to something that you didn't explicitly alloc yourself. If you didn't alloc it, odds are it was autoreleasing itself, and you sending a release to it takes the retain count negative, and the Foundation framework vomits with an EXC_BAD_ACCESS.

Zombie Messaged In For Loop

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.