2

文字列の文字を次のように変更する、Visual C++ 2008 で古典的な C 開発を行おうとしています。

void ModifyString(char *input)
{
  // Change first character to 'a'
  *input = 'a';
}

キャラクターを変更しようとすると、未処理の例外が発生します。Visual Studio 6 または gcc を使用してこれを行うことができるようですが、何かを忘れているだけかもしれません。Visual Studio はどうにかして char* を値で渡しますか (メモリの管理)。もしそうなら、どうすればこれをオフにできますか?

4

4 に答える 4

8

おそらくどこかに文字列リテラルを渡しているでしょう:

ModifyString("oops");  // ERROR!

C および C++ では、文字列リテラル (型はconst char[])から に暗黙的にキャストできますchar*が、そのような使用法は非推奨です。文字列定数は読み取り専用メモリに割り当てることが許可されているため (通常は割り当てられています)、それらを変更しようとすると、アクセス違反 (セグメンテーション違反またはバス エラー) が発生します。コンパイラが文字列定数を読み取り専用メモリに配置しない場合でも、プログラムは動作しますが、未定義の動作です。

これを行う正しい方法は、文字列を書き込み可能なバッファにコピーすることです。

// one way:
char mystring[] = "test";
ModifyString(mystring);  // ok

// another way:
char mystring[64];  // make sure this is big enough!!
strcpy(mystring, "test");
ModifyString(mystring);  // ok
于 2009-07-11T17:45:40.083 に答える
1

入力は文字列リテラルですか? それがおそらく問題です。それ以外の場合は、ポインターがメモリ内の読み取り専用の場所を指しているため、さらにコードを投稿する必要があります。

于 2009-07-11T17:38:02.847 に答える
1

ModifyString がどのように呼び出されるかを知らずに、この質問に答えることは不可能です。関数自体は、コントラクトが NULL 以外の値を渡されると仮定すると正しいです。

ただし、さまざまなことを行うことで呼び出しサイトが失敗する可能性があります

  • NULL を渡す
  • 邪悪なキャストによる const char の受け渡し
于 2009-07-11T17:38:20.020 に答える
0

これが機能しない理由を正確に言うことはできませんが、問題は Visual Studio ではなくコードにあります。何らかの理由で、無効なポインターを関数に渡しています。null ポインターであるか、読み取りアクセス権のないアドレスを指しています。

もう少しコードを投稿していただければ (関数はどこから呼び出され、どのように呼び出されるのか?)、正確な問題を指摘できるかもしれません。

GCC または VC6 で機能した理由は、単純に未定義の動作だからです。C++ 標準は、「これで動くはずだ」とか「これでクラッシュするはずだ」とは言っていません。アクセスできないメモリに書き込むと、何かが起こる可能性があります。また、コンパイラやアプリケーションを実行しているシステムによって、最終的にアクセスするアドレスは異なります。運が良ければ、VC2008 でコンパイルしたときにアクセス違反が発生するアドレスにヒットしました。GCC と VC6 の下では、あなたは幸運ではなく、動作しているように見えるコードを取得、単にいくつかのガベージ アドレスに書き込みました。

于 2009-07-11T17:46:40.393 に答える