澄清了 strcpy() 在像这样初始化字符数组时的工作 *Arr.

Clarification of working of strcpy() when char array has been initialized like this *Arr

本文关键字:数组 字符 工作 Arr 初始化 像这样 strcpy      更新时间:2023-10-16

我正在尝试这样strcpy

int main()
{
char *c="hello";
const char *d="mello";
strcpy(c,d);
cout<<c<<endl;
return 0;
}

编译此代码会发出警告,运行代码会产生分段错误。

警告是:

警告:已弃用从字符串常量到"char*"的转换 [-Wwrite-strings]
char *c="hello";

strcpy的声明是:char * strcpy ( char * destination, const char * source );

  1. 那么我错在哪里(关于警告(?IMO 我使用了const charchar,与函数的声明相同。

  2. c*d*是否不分配内存来容纳"hello""mello",由于 这是抛出分段错误?如何 像c*工作一样的变量的初始化/定义?

这两个变量都指向常量文字文本。

修改常量文本是未定义的行为。

如果要修改文本,请将文本放入数组中:

char e[] = "fred";
e[0] = 'd';

编译器警告(和错误(总是引用特定的代码行(以及该行的一部分(。密切关注问题所在是个好主意。

在您的情况下,警告不是关于调用strcpy,而是关于初始化c。您正在创建一个char *,一个指向可修改char的指针,指向"hello",一个只读字符串文本。这就是编译器警告您的内容。

这在C++中曾经是可能的,但需要注意的是,您永远不能实际修改指向的内存(因为字符串文字是不可变的(。自 C++11 以来,将字符串文本转换为char *是绝对禁止的,并且将生成错误而不是警告。

段错误的原因现在应该很清楚了:您正在尝试使用strcpy调用覆盖一段只读内存。

正确的解决方案是使用可写内存来存储目标字符串。你可以这样做:

char c[] = "hello";

这将创建一个新的char数组,该数组通常是可写的(就像任何其他局部变量一样(,并使用字符串文本的内容(实际上是其副本(初始化数组。

当然,由于这是C++,你应该使用std::string来存储字符串,而根本不用char*strcpy和其他C-isms。

您正在尝试的代码似乎是针对TurboC ++的。正如drescherjm在评论中指出的那样,char *c="hello";在c ++中不再合法。

如果您在 Turbo C++ 中试用您的代码,它将按预期工作,尽管现代 c++ 的情况不同。

那么我错在哪里(关于警告(?IMO 我使用了常量字符和字符,与函数的声明相同。

警告是由于上述原因,而且警告不是关于使用 strcpy,而是在声明上。

c* 或 d* 是否没有分配内存来保存 "hello" 和 "mello",因此它会抛出分段错误?像 c* 这样的变量的初始化/定义是如何工作的?

好吧,编译器只是将字符串放在内存中的随机位置,让 c/d 指针指向它。这是有风险的,因为如果您意外地将指针指向其他内容,您可能会丢失数据。