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函数并不总是空终止字符串。这是这种情况,因为strlen("Hello")大于3(您的最后一个strncpy参数)。

于 2012-04-30T18:20:31.123 回答
0

如果您希望能够修改字符串,那么您需要像这样分配字符数组

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

正如其他人所说,问题在于您的方法导致编译器创建一个包含 3 个指向常量字符串的指针的数组。上面的声明创建了一个二元字符数组,然后将常量字符串数据复制到该内存中。

于 2012-04-30T18:28:57.563 回答