1

破損している const 文字列リテラルがあります。

奇妙なのは、インストールされている XCode のバージョンによって動作が明らかに異なることです (これを 100% 確認する前に、さらにいくつかの実験を行う必要があります)。何が原因なのだろう。

まったく同じコードがまったく同じハンドセットで実行されているが、1 つの実行が Xcode 3.3.3 を実行しているラップトップに接続されている場合、同じコードと同じハンドセットが XCode 4.3.2 を搭載した別のラップトップで実行されている場合、この問題が明らかになります。または 4.4 がインストールされている場合、問題は発生しません。

問題はこれです:

HeaderFile.h
extern NSString* const kValue;

HeaderFile.m
NSString* const kValue = @"Some Value";

OtherFile.m
#import "HeaderFile.h"
...
NSLog(@"Value is: %@", kValue);

Xcode 4.3.3 を使用してラップトップに接続すると、グローバル定数のデバッグ時に記録または観察される値が破損します。

これがどのようになるかについてのアイデアはありますか?

これは const リテラルであるため、コードにバグがある場合に走り書きを行うことはできません。

更新: didFinishLaunchingWithOptions: が呼び出された直後に kValue の値を調べましたが、その時点で既に破損しているため、たとえ落書き可能であっても、コードが落書きする機会はありません。

4

1 に答える 1

1

これは const リテラルであるため、コードにバグがある場合に落書きすることはできません。

それは完全に真実ではありません。

まず、単純なキャストで const を削除することもできます。次に、重大なバグがある場合、別の変数のメモリを超えてアクセスしているため、変数を格納するメモリに書き込んでいる可能性があります(たとえば、 a のアドレスを取得してshort型にキャストしてからlong*アクセスする場合)。3 番目に、ポインター自体が const と宣言されていますが、ポイントされているデータは const ではありません (少なくとも宣言によれば)。

一方で、一般的に、あなたが観察したことが不可能である可能性があるのは事実です。多くの場合、const と宣言されたグローバルは、実行時に読み取り専用のメモリ領域に配置されます。しかし、すべてのハードウェアがこれを許可しているわけではなく、これを行う必要があるコンパイラーの実際の要件はありません。また、通常、文字列リテラルも const と見なされます。つまり、実際には、ポインタが const でなくても、指している内容も const 領域に格納される可能性があります。

なぜそのような動作が見られるのかわかりませんし、コンパイラと iPhone ハードウェアの内部構造もわかりません。そのため、バグのためにそのデータを変更することが実際に不可能かどうかはわかりません。しかし、言語規則により、コンパイラ (およびハードウェア) がすべてを変更可能な領域に格納することは完全に合法であることを知っています。そして、それが彼らのすることなら、はい、バグが問題かもしれません。

于 2012-08-23T03:43:30.047 に答える