1

次のコードがあるとします。

#include "stdafx.h"
#include "string.h"
static char *myStaticArray[] = {"HelloOne", "Two", "Three"};

int _tmain(int argc, _TCHAR* argv[])
{
    char * p = strstr(myStaticArray[0],"One");
    char hello[10];
    memset(hello,0,sizeof(hello));
    strncpy(hello,"Hello",6);
    strncpy(p,"Hello",3); // Access Violation
    return 0;
}

myStaticArray[0] のアドレスに書き込もうとしたまさにその時点でアクセス違反が発生しています。なぜこれが問題なのですか?

背景: 私は主に C# 開発者として古い C++ を C# に移植しているので、私の無知を許してください! このコードは古いビルドでは明らかに問題ではなかったので、混乱しています...

4

3 に答える 3

5
char * p = strstr(myStaticArray[0],"One");

p文字列リテラル「HelloOne」の一部を指します。文字列リテラルを変更しようとしてはいけません。これは未定義の動作です。

多くの場合、文字列リテラルはメモリの読み取り専用部分に格納されるため、それらに書き込もうとすると、セグメンテーション違反/アクセス違反が発生します。

于 2012-04-30T18:20:06.100 に答える
2
 static char *myStaticArray[] = {"HelloOne", "Two", "Three"};

配列内の文字列は文字列リテラルであり、C および C++ では変更できません。

strncpy(p,"Hello",3);

この関数呼び出しは、文字列リテラルを変更しようとします。

別の問題は、strncpy常に文字列を null で終了するとは限らない関数の使用です。これは、 (最後の引数)strlen("Hello")より大きいためです。3strncpy

于 2012-04-30T18:20:31.123 に答える
0

文字列を変更できるようにしたい場合は、このように文字配列を割り当てる必要があります

static char myStaticArray[][25] = {"HelloOne", "two", "three"};

他の人が述べたように、問題は、あなたのメソッドがコンパイラに定数文字列への3つのポインタの配列を作成させることです。上記の宣言は、2 次元の文字配列を作成し、定数文字列データをそのメモリにコピーします。

于 2012-04-30T18:28:57.563 に答える