2012-03-05 4 views
3

私は、次の方法があります。オブジェクトが明らかにクラッシュが発生しませんが、まれにしか

+ (NSString*) getMD5HashFromFile:(NSString*)filePath { 
    CFStringRef md5hash = FileMD5HashCreateWithPath((CFStringRef)filePath, FileHashDefaultChunkSizeForReadingData); 
    NSString *hashStr = (NSString*)md5hash; 
    CFRelease(md5hash); 
    return hashStr; 
} 

私は約1 20-30の実行中に、シミュレータ上でのランダムなクラッシュを得ていたが。これが一貫していなかったという事実は、以前より深く掘り下げるのに役立ちませんでした。

コードがもう一度表示されたので、md5hashが返される前に解放されることは明らかです。つまり、返されたオブジェクトは無効になります。返される値は、別のメソッドで一貫して使用され、時々クラッシュすることがありますが、必ずしもそうではありません。私の質問は、これがまれにしか起こらず、必ずしも起こらない理由です。

Obj-CとCコードの組み合わせ、および自動解放プールの働きは何ですか?

注:バグはNSString *hashStr = [NSString stringWithString:(NSString*)md5hash]を使用して解決されているようですが、それは私には分かります。

答えて

5

メモリが解放され、割り当てが解除されただけで、すぐにOSに戻されるわけではありません。あなたのアプリケーションは、数多くの要素やいくつかのレイヤーに基づいて、任意の期間にわたってそのアプリケーションを保持することができます。 OSには、あなたが放棄したすべてのメモリを取り戻すよりも、時にはもっと重要なことがあります。 free()と呼ばれているが技術的に所有しているメモリにアクセスすると、シグナルは生成されません。このため、MallocScribbleが存在します。ゴミ箱(0x55)で解放したメモリは上書きされるため、解放されたメモリを使用するとより明確になります。

次のことを試してみてください。

char *foo = malloc(100); 
strcpy(foo, "stuff"); 
free(foo); 
printf("%s", foo); 

完全に間違っているにもかかわらず、正常に動作しますほとんどの時間。ここで、[スキーム]> [診断]と[スクラブルを有効にする]を編集します。再実行すると、ナンセンスを読んでいることを示す「U」(0x55)の束が表示されます。しかし、それはまだクラッシュしません。

マットギャラガーのA look at how malloc works on the Macについてもう少し詳しくは、こちらをご覧ください。

+0

がクラッシュしますが、あなたにロブをありがとうございました。これはかなり良い説明だと思います。実際、私はそれが書かれていることを知ったので、私はすでにこれを新しいことを理解しています。明らかに十分ではない:)再びありがとう – dimitrios

+0

私たちは私たちが思い出したはずのものを忘れる:D https://twitter.com/#!/cocoaphony/status/174989186032603136 –

0
+(NSString*) getMD5HashFromFile:(NSString*)filePath { 
    CFStringRef md5hash = FileMD5HashCreateWithPath((CFStringRef)filePath, FileHashDefaultChunkSizeForReadingData); 
    NSString *hashStr = [(NSString*)md5hash copy]; 
    CFRelease(md5hash); 
    return [hashStr autorelease]; 
} 

長時間電話をかける必要がある場合は、呼び出し元に戻り値を保持してください。

2

CFRelease引数はNULLであってはなりません。

CFRelease引数がNULLの場合、これはランタイムエラーが発生しますし、 アプリケーションが

if(md5hash) 
CFRelease(md5hash); 
関連する問題