C 写入静态全局变量时发生访问冲突?

C 写入静态全局变量时发生访问冲突?,c,string,C,String,给定以下代码: #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));

给定以下代码:

#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开发者,所以请原谅我的无知!这段代码在旧版本中显然不是问题,所以我很困惑

char * p = strstr(myStaticArray[0],"One");
p指向字符串文字HelloOne的一部分。不能试图修改字符串文字,这是未定义的行为

通常,字符串文本存储在内存的只读部分,因此尝试写入它们会导致分段错误/访问冲突

 static char *myStaticArray[] = {"HelloOne", "Two", "Three"};
p指向字符串文字HelloOne的一部分。不能试图修改字符串文字,这是未定义的行为

通常,字符串文本存储在内存的只读部分,因此尝试写入它们会导致分段错误/访问冲突

 static char *myStaticArray[] = {"HelloOne", "Two", "Three"};

数组中的字符串是字符串文字,C和C++中不可修改。

strncpy(p,"Hello",3);
此函数调用尝试修改字符串文字

另一个问题是您对strncpy函数的使用,该函数并不总是以null终止字符串。这里的情况是这样的,因为strlenHello大于最后一个strncpy参数的3

数组中的字符串是字符串文字,C和C++中不可修改。

strncpy(p,"Hello",3);
此函数调用尝试修改字符串文字


另一个问题是您对strncpy函数的使用,该函数并不总是以null终止字符串。这里的情况是这样的,因为strlenHello大于最后一个strncpy参数的3

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

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

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

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

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

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

正如我所怀疑的,答案很简单,谢谢你的快速回复。在旧得多的编译器中是否允许这样的操作?@Riken:它可能在一些旧的编译器上工作,但它始终是未定义的行为。@Riken字符串文字可以作为C扩展进行修改,因此在某些实现中可以修改。哦,据我所知,它始终是未定义的行为。但我不是历史专家。但是,未定义的行为包括在使用特定编译器时按预期工作的可能性。@ouah:这只是因为它曾经错误地允许它,并且他们希望客户的代码继续编译。不要使用那个分机或任何其他你不必使用的分机。我猜答案很简单,谢谢你的快速回复。在旧得多的编译器中是否允许这样的操作?@Riken:它可能在一些旧的编译器上工作,但它始终是未定义的行为。@Riken字符串文字可以作为C扩展进行修改,因此在某些实现中可以修改。哦,据我所知,它始终是未定义的行为。但我不是历史专家。但是,未定义的行为包括在使用特定编译器时按预期工作的可能性。@ouah:这只是因为它曾经错误地允许它,并且他们希望客户的代码继续编译。不要使用那个扩展或者任何你不需要的扩展。这不是C++。基本上是C,根本不与好的C++代码有关系。这不是C++。基本上是C,根本不与好的C++代码相关。