Reputation: 493
Here's a piece of code I wrote for cleaning A string of unwanted chars and double spacing. However, I seem to have misunderstood memory management somewhere and it keeps causing the EXC_BAD_ACCESS error. The Code works fine functionally when the release statements are removed but that would cause memory leaks.
-(NSString*) cleaningString:(NSString*) input {
NSCharacterSet* wantedCharacters=[[NSCharacterSet alloc] init];
wantedCharacters=[ NSCharacterSet
characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnm"];
NSString* cleanStringOutput=[[NSString alloc] initWithString:@""];
NSString* currentLetter =[[NSString alloc] initWithString:@" "];
NSRange unwantedCharacters=[currentLetter rangeOfCharacterFromSet:wantedCharacters];
for (int i=0; i<input.length; i++) {
currentLetter=[NSString stringWithFormat:@"%c",[input characterAtIndex:i]];
unwantedCharacters=[currentLetter rangeOfCharacterFromSet:wantedCharacters];
doubleSpace=YES;
if (i<input.length-1) {
if (([currentLetter isEqualToString:@" "])&&([[NSString stringWithFormat:@"%c",[input characterAtIndex:i+1]] isEqualToString:@" "])) {
doubleSpace=NO;}
}
else {
if ([currentLetter isEqualToString:@" "]) {
doubleSpace=NO;
}
}
if ((unwantedCharacters.location!=NSNotFound)&&(doubleSpace))
{
cleanStringOutput=[NSString stringWithFormat:@"%@%@", cleanStringOutput, currentLetter];
}
}
if (cleanStringOutput.length>0){
if ([[NSString stringWithFormat:@"%c",[cleanStringOutput characterAtIndex:0]] isEqualToString:@" "]){
cleanStringOutput=[cleanStringOutput substringFromIndex:1];
}
}
[currentLetter release];
[wantedCharacters release];
[cleanStringOutput autorelease];
return cleanStringOutput;
}
Please forgive me if I just asked something painfully obvious.
P.S. And another question. Is it necessary to release the NSRange?
Upvotes: 1
Views: 414
Reputation: 5960
You alloc/init a wantedCharacters
object, then reassign it using a convenience function. The reassignment creates a zombie with the first object.
The convenience function puts the new object instance into the autorelease pool.
Then you call release. Since it was only retained once, it gets deallocated.
Later, the autorelease pool calls release on it, but it has already been deallocated. This causes the crash.
Upvotes: 0
Reputation: 17372
Right here
NSCharacterSet* wantedCharacters=[[NSCharacterSet alloc] init];
wantedCharacters=[ NSCharacterSet
characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnm"];
You discard your original object and replace it with an autoreleased one
Which will crash when you call
[wantedCharacters release];
Do this
NSCharacterSet* wantedCharacters=[ NSCharacterSet
characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnm"];
and forget the last
[wantedCharacters release];
Upvotes: 1
Reputation: 13397
currentLetter=[NSString stringWithFormat:@"%c",[input characterAtIndex:i]];
Returns an autoreleased string - no need to alloc/init it above.
NSString* currentLetter =[[NSString alloc] initWithString:@" "];
So calling
[currentLetter release];
Will probably cause problems.
Upvotes: 0
Reputation: 137282
There are several mistakes in your code that causes you to lose the reference to the allocated objects, and an example will follow, but a few things:
The easiest solution for all of them, is to use autorelease
wherever you call alloc
(and remove the release
for those objects), for example:
NSString* cleanStringOutput=[[[NSString alloc] initWithString:@""] autorelease];
When you create a variable only to assign to it later, there is no need to allocate, for example:
NSCharacterSet* wantedCharacters; // no need for alloc here
wantedCharacters=[ NSCharacterSet characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnm"];
In general - if you didn't allocate the object, you don't release it.
Upvotes: 0