2013-06-24 3 views
0

Мне нужно преобразовать NSString в std :: string и успешно с помощью [str UTF8String]. Но по какой-то причине, когда я пытаюсь использовать один из своих NSStrings, я получаю ошибку EXC_BAD_ACCESS.NSString UTF8String плохой доступ

Я проверяю, что str не является нулевым, поэтому я не уверен, почему это происходит. Я также пытался убедиться, что str действительно является NSString, но следующее бросает ту же ошибку:

const char* className = class_getName([str class]); 

Что мне не хватает?

EDIT: код, я использую:

NSMutableArray* m_imageInfos; // defined in ClassName.h 
RUBEImageInfo *touchedImgInfo; // also defined in ClassName.h 

Это проект cocos2d, и в зависимости от потока игры я загружаю дополнительные объекты типа RUBEImageInfo в m_imageInfos. Соответствующий код:

RUBEImageInfo* imgInfo = [[RUBEImageInfo alloc] init]; 
imgInfo->sprite = sprite; 
imgInfo->name = [NSString stringWithUTF8String:newImg->name.c_str()]; 
std::cout << "loadBody imgInfo name " << [imgInfo->name UTF8String] << "\n"; 

std :: cout правильно печатает изображение. Я хотел бы добавить, что имя является конкатенация строки Ан INT, как это:

std::stringstream sstm; 
sstm << img->name << counter; 
newImg->name = sstm.str(); 

В ClassName.mm, CCTouchesBegun я проверяю, который b2Body в трогают, а затем цикл по m_imageInfos, чтобы увидеть whicn ImageInfo был прикоснулся:

for(int j=0; j<[m_imageInfos count]; j++) { 
    RUBEImageInfo *rif = m_imageInfos[j]; 
    if(rif->body == body) { 
     touchedImgInfo = rif; 
     printf("ccTouchesBegun touchedImgInfo %p \n", touchedImgInfo); 
     printf("ccTouchesBegun touchedImgInfo name %p \n", [touchedImgInfo->name UTF8String]); 
      break; 
    } 
} 

Первая распечатка проходит хорошо и дает результат:

ccTouchesBegun touchedImgInfo 0x98b84f0 

но второй ошибку отпечатков с EXE_BAD_ACCESS. Чтобы добавить сложность, это происходит только в большинстве случаев. Один раз в каждые 10-15 попыток он работает нормально.

Для полноты кода, это RUBEImageInfo.h:

#import "cocos2d.h" 

@interface RUBEImageInfo : NSObject { 

    @public CCSprite* sprite;    
    @public NSString* name;     
    @public class b2Body* body;    
    @public float scale;      
    @public float angle;      
    @public CGPoint center;     
    @public float opacity;     
    @public bool flip;      
    @public int colorTint[4];    
} 

@end 
+0

Итак, 'std :: string s ([@" foo "UTF8String])' segfault также? –

+0

Что делает 'NSLog (@"% @ ", str)' do? Если это также seg-ошибки, я бы сказал, что 'str' - объект зомби. – JeremyP

+0

Да, это ошибка на обоих. Что значит объект зомби? – Eddy

ответ

1
imgInfo->name = [NSString stringWithUTF8String:newImg->name.c_str()]; 

Это неправильное управление памятью. Вы напрямую назначаете объект, который не принадлежит переменной экземпляра другого объекта. Он будет работать, если вы используете его в том же методе, но жизнь этого объекта не гарантируется за счет жизни текущего пула авторесурсов. Поэтому в конечном итоге переменная экземпляра указывает на мусор.

В идеале вы должны использовать аксессоры вместо назначения переменных экземпляра напрямую. Это идиоматический подход в приложениях Cocoa. Если вы по какой-то причине просто не можете использовать аксессоры, тогда вам нужно обязательно убедиться, что вы правильно управляете своей памятью везде, где используется переменная экземпляра.

+0

Спасибо @Chuck. В этих объектах нет геттеров или сеттеров, так как бы вы выполнили задание? – Eddy

+0

@Eddy: Вы освободите текущее значение (чтобы не просочиться) и сохраните новый, если вы еще не владеете им. – Chuck

+0

любой шанс для примера? Я новичок в C++/Obj-C, и это для меня все еще нечеткое. (Я знал, что в какой-то момент я пропущу Java, возможно, скорее раньше, чем позже) – Eddy