Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C Result from a Static Method saved to class instance variable giving "EXC_BAD_ACCESS" when used

I am trying to store the md5 string as a class instance variable instead of the actual password. I have a static function that will return a md5 string which I'm trying to store in an instance variable instead of the actual password.

I have the following setter for my class instance variable:

-(void)setPassword:(NSString *)newpass{
 if(newpass != password){
  password = [utils md5HexDigest:newpass];
 }
}

This will pass back the correct md5 string and save it to the password variable in my init function: [self setPassword:pword];.

If I call another instance method and try to access self.password" I will get "EXC_BAD_ACCESS".

I understand that the memory is getting released, but I have no clue to make sure it stays.

I have tried alloc init with autorelease with no luck.

This is the md5HexDigest function getting called during the init (graciously found in another stackoverflow question):

+ (NSString*)md5HexDigest:(NSString*)input {
  const char* str = [input UTF8String];
  unsigned char result[CC_MD5_DIGEST_LENGTH];
  CC_MD5(str, strlen(str), result);

  NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];

  for(int i = 0; i<CC_MD5_DIGEST_LENGTH; i++)
    [ret appendFormat:@"%02x",result[i]];

  return ret;
}  

Any help/pointers would be greatly appreciated. I would rather have the md5 string saved in memory than the actual password calling the md5 every time I needed to use the password.

Thanks in advance.

like image 524
KinGBin Avatar asked Jan 12 '11 04:01

KinGBin


3 Answers

Both David and pwc are correct, but missing an important detail.

setPassword: should copy the inbound parameter. This will both ensure that

  • it is retained properly as the other answers imply and also that
  • the set string is no longer mutable.

i.e. something like:

-(void)setPassword:(NSString *)newpass{
    [password release];
    password = [[utils md5HexDigest: newpass] copy];
}
like image 165
bbum Avatar answered Oct 19 '22 07:10

bbum


Your setter needs to retain the new value (the one returned from [utils md5HexDigest:newpass]). (and don't forget to release the old value too...)

Also, the test if(newpass != password) does not make any sense: newpass is an actual password, but password is the md5 digest.

like image 24
David Gelhar Avatar answered Oct 19 '22 08:10

David Gelhar


The NSString returned by md5HexDigest is autoreleased (because NSMutableString stringWithCapacity returns an autoreleased string). You need to retain it in setPassword. Otherwise, it is being freed by the autorelease pool.

like image 34
pwc Avatar answered Oct 19 '22 08:10

pwc