澄清了 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;
}
编译此代码会发出警告,运行代码会产生分段错误。
警告是:
警告:已弃用从字符串常量到"char*"的转换 [-Wwrite-strings]
char *c="hello";
strcpy
的声明是:char * strcpy ( char * destination, const char * source );
那么我错在哪里(关于警告(?IMO 我使用了
const char
和char
,与函数的声明相同。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 指针指向它。这是有风险的,因为如果您意外地将指针指向其他内容,您可能会丢失数据。
- 指向指向字符数组的指针数组的指针
- 比较字符数组
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- 使用无符号字符数组有效存储内存
- 按字符值访问int数组
- 错误:字符数组的初始值设定项太多
- 对字符数组中的元素执行逐位操作
- C++,在int数组中输入字符串或字符会输出0,而不是ascii或error
- C++ 无法在字符数组中使用 for 循环打印字母模式
- 如何在 C++ 中从文件中读取字符数组(带有一些空格)
- 移动二维数组中的字符
- C++ 传递二维字符数组
- 无法在 C++ 中输入字符数组
- C++ 带结构的数组字符
- 数组字符包含量超出预期
- 读取文件并添加到数组字符
- 如何在Qt中更改或替换数组字符
- 为什么编译器不在参数中传递数组字符 *arr[] 的大小?
- 井字棋数组字符错误
- 分割数组字符