像这样初始化 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 );
那么我哪里错了(关于警告)? IMO 我使用了 const char
和 char
,与函数的声明相同。
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 语言。
我正在尝试 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 );
那么我哪里错了(关于警告)? IMO 我使用了
const char
和char
,与函数的声明相同。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 语言。