2012-01-06 4 views
1

const char文字列が初期化された後に壊れてしまう不思議な問題が発生しました。Objective-C:const char *文字列が壊れている:何が起こっているのですか?

私はそうのようにポインタを宣言している私の.mファイルで

const char *s; 

@implementation MyClass 
... 
@end 

それは-initに初期化され、その時点で正常に見えるです:

-init 
{ 
    if (self = [super init]) { 
     s = [@"obfuscatedString" deobfuscatedCString]; 
    } 
    return self; 
} 

その後、私は読むために来たときにポインタのアドレスは変更されませんが、値は上書きされています。

私は裸の必需品にそれを取り除き、文字列が他の方法で使用されていないことを確認し、それを破損する可能性があるとは思われません。

どうしたの?目的のいくつかの基本的なビットがありますか?私は気づいていませんか?

ご協力いただければ幸いです。あなたは本当に私たちに多くの情報を与えていない

+0

あなたは '-init'方法を投稿してくださいもらえますか? – dasblinkenlight

+0

私はobjective-Cで精巧ではありませんが、一般的に、範囲外のインデックスで配列にアクセスする、解放されたメモリブロックを使用するなど、間違ったメモリ操作によって破損が引き起こされる可能性があります。デバッガを使用して、メモリが変更された正確な場所を検出してみてください。また、いくつかのツールを使ってヒープエラーを捕まえることができます(Rational Purifyなど) –

+0

'init'に' S'を設定しません。あるいは、グローバル変数は実際に 'SBSERVPATH'と呼ばれていますか? – mipadi

答えて

0

deobfuscatedCString使用の自動解放オブジェクトをしていますか?返されたアドレスが、それらのうちの1つが解放されたときに解放されるメモリを指しているかもしれません。

そのような場合は、あなたはまだschar *になりたい場合は、試してみてください。

s = strdup([@"obfuscatedString" deobfuscatedCString]); 
+0

はい!オートレリースされていたことが分かります。 -cStringUsingEncodingがCのポインタを管理することを期待していなかったのは、Cocoaオブジェクトでした。助けてくれてありがとう。 –

2

、私はそれがどのような場合には、悪いコーディングスタイルだと思います:)

を知っているので、私のアドバイスは、次のようになります。Sインスタンス変数を作ります。本当に。

+0

Sは文字列定数のように使用されるので、クラス変数である必要がありますが、使用するたびに不必要に高価になるため、実行時に作成する必要があります。 –

2

これは、Cの文字列のメモリがある時点で解放されるためです。あなたが絶対にそのグローバルを持っている必要があるなら(そしてコンストラクタからそれを初期化するという事実から、完全に正しくないかもしれないと思われます)、NSString *にしてください。明示的にリリースされるまで、その値を保持します。 char*への変換が必要な場合はいつでもcStringUsingEncodingを使用してください。

0

何が起こっているのかわからないようなコードはありませんので、ここでお手伝いすることはできません。詳細を教えてください。

しかし、あなたはあなたの質問のコードの唯一の3行を記述しなかった場合でも、とにかく、これはすでに恐ろしいコーディングスタイルです:

  • あなたはのconstのcharを使用* NSStringのは、他のCocoaで動作するように、おそらくより適切であるのに対し、オブジェクト
  • グローバル変数を使用すると、コーディングスタイルが悪くなります(同時アクセスの問題など)。代わりにインスタンス変数を使用してください。本当に。
  • あなたの変数名は1文字だけです。これは本当に悪い習慣であり、コードを分かりやすくするのに役立ちません。 "S"のような名前は説明にはほど遠い
  • 大文字で始まる変数の名前は大文字で始まりますが、大文字で始まる名前はクラス名用に予約する必要があり、インスタンス変数は小文字でスタードする必要があります。これが定数の場合は、大文字で表記することができますが、タイトル名は大文字ではありませんが、変数名は1文字の長さにすぎません...

要するに、プログラミングガイドを読んで、良い習慣を使ってください(厳密に必要でなければchar*のグローバル定数を避けてください)、後でデバッグするのが難しいエラー(メモリ破損など)につながります。また、元の問題を解決するために、より多くのコードを使用してください。

+0

詳細を通知しないことに対するお詫び:これは仕事用であり、実際のコードを投稿することはできません。これは単なる擬似コードです。 Cocoaオブジェクトを使用する場合 - はい、それでも動作しますが、C関数で文字列を使用するたびに追加の手順が必要になります。これは*うまくいくはずです。 –

0

何らかの点でポインタやその内容に悩まされているようです。私は、クラスメソッドで定数をラップし、その中からのみ変更することを確認します。このような何か:deobfuscatingとき

+ (const char *)globalCString 
{ 
    static const char *s = NULL; 
    if (!s) s = [@"obfuscatedString" deobfuscatedCString]; 
    return s; 
} 
関連する問題