3

ファイルで宣言された静的変数があります。

static char *msgToUser[] = {
    "MSG1                ", 
    "MSG2                ",
};

クラスのメソッドの1つの中で、私はこれをやっています:

void InfoUser::ModifyMsg( BYTE msgIdx, char *msgString ){
    strncpy( msgToUser[ idx ], msgString, DISPLAY_SIZE );
}

strncopy を実行すると、プログラムがクラッシュします。何が間違っているのかわかりません

4

4 に答える 4

6

定義した配列は、文字列へのポインターの配列です。各文字列はリテラル(つまり、ポインタとして解釈される引用符で囲まれた文字列) です。これは、定数として宣言していなくても、定数であることを意味します。文字列リテラルは変更できません。

それらを変更できるようにしたい場合は、明示的な配列割り当てを使用できます。

// Note: The space padding isn't needed if all you require is that the string
// be able to hold DISPLAY_SIZE characters (incl the null terminator)
static char str_1[DISPLAY_SIZE] = "MSG1                ";
static char str_2[DISPLAY_SIZE] = "MSG1                ";
static char *msgToUser[] = { str_1, str_2 };
于 2010-08-30T12:33:25.900 に答える
2

C-FAQ を参照してください。質問1.32

于 2010-08-30T12:33:53.970 に答える
0

配列をポインターの配列として保持する代わりに、スペースを割り当てる文字の 2 次元配列にします。

現在、これは char * の配列であり、文字列リテラルを使用して初期化が行われているため、文字列リテラルの読み取り専用メモリを上書きしようとすると、クラッシュします。

于 2010-08-30T12:33:46.320 に答える
0

msgToUser を文字ポインターのベクトルとして定義しました。これらの文字ポインタは、読み取り専用としてマークされたメモリに格納されている文字列 (文字配列) を指します (Microsoft の Visual Studio では、コンパイラ オプションを使用してこれを変更できます)。

したがって、このメモリを変更すると、プロセッサが例外を発生させ (読み取り専用メモリに書き込もうとしている)、アプリケーションがクラッシュします。

于 2010-08-30T12:33:52.327 に答える