像这样初始化 char 数组时 strcpy() 的工作说明 *Arr

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

我正在尝试 strcpy 像这样:

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

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

警告是:

warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
char *c="hello";

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

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

  2. c*d* 没有分配内存来保存 "hello""mello",因为 它抛出分段错误?如何 initialization/definition 像 c* 这样的变量有效吗?

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

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

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

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

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

如果您在 Turbo C++ 中试用您的代码,它会像您预期的那样工作,尽管这与现代 c++ 的情况不同。

So where am I wrong (regarding the warning)? IMO I have used a const char and a char, same as the function's declaration.

警告是因为上面提到的原因,加上警告不是关于strcpy的使用,而是在声明上。

Does c* or d* not allocate memory to hold "hello" and "mello", due to which it is throwing segmentation fault? How does the initialization/definition of a variable like c* work?

好吧,编译器只是将字符串放入内存中的随机位置,并让 c/d 指针指向它。这是有风险的,因为如果你不小心将指针指向其他东西,你可能会丢失数据。

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

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

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

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

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

char c[] = "hello";

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

当然,因为这是 C++,你应该使用 std::string 来存储字符串,而不用理会 char*strcpy 和其他 C 语言。