2013-04-10 15 views
9

私が理解できるように、MSDN C#の固定声明によると同じように動作する必要がありますので、安全でない文字列ポインタ声明

fixed (char* p = str) ... // equivalent to p = &str[0] 

、なぜ私はこれを行うcan`t?

const string str = "1234"; 
    fixed (char* c = &str[0]) 
    { 
/// ..... 
    } 

たとえば、str[1]へのポインタを取得するにはどうすればよいですか?

+0

どのようなエラーが表示されますか? –

+0

コンパイル時エラー: 与えられた式のアドレスを取ることができません –

+0

[指定された式のアドレスを取ることができません\t C#ポインタ](http://stackoverflow.com/questions/5079736/cannot-take-the-指定された式のアドレスポインタ) –

答えて

4

これは、文字列の[]演算子が値を返すメソッドであるためです。メソッドからの戻り値は、プリミティブ型のアドレスではありません。 C#で

[]オペレータはCでCの[]と同じではない、配列や文字列は単なるポインタであり、ポインタに[]演算子を適用して、ポインタを移動し、それを逆参照することと等価です。これはC#で保持されません。

は、実際にエラーがリンクされているMSDNのドキュメントにあった、それはこの正確な問題の詳細な説明を参照してくださいherelatest version.

に固定されています。

+0

"メソッドからの戻り値にはアドレスがありません。"それはまったく真実ではありません。 'string [int]'の返り値は 'fixed'になる型ではない' char'です。 –

1

fixedステートメントの要点は、メモリ割り当てが仮想メモリを横断するのを防ぐことです。メモリ割り当ては、他のアドレスではなく、その先頭で識別されます。

&str[1]を固定しておくには、実際にはstrが固定されている必要があります。ポインタの算術演算を使用して、固定ポインタからstrまでの単一の割り当て内の他のポインタを派生させることができます。

0
これにあなたのコードを変更

char[] strC = "1234".ToArray(); 
fixed (char* c = &strC[0]) 
{ 
    /// ..... 
} 
+0

これは、最初の文字を保持するメモリ位置を指すアドレスを与えますが、文字列の他の文字にアクセスするために使用することはできません。 –

7

以降の要素へのポインタを取得することは、直接配列で動作しますが、唯一の理由は、MSがそれを実装していないということであるように、文字列とそれはそうではないので。配列のセマンティクスに従うことで、それを簡単に設計することができました。

しかし、他の配列要素を指す別のポインタを簡単に計算できます。したがって実際には大きな問題ではありません。

fixed (char* p = str) 
{ 
    char* p1 = p+1; 
} 
関連する問題