与教科书上关于未调整大小的数组初始化C++句子的混淆
Confusion with textbook sentence on unsized array initialization C++
我正在读一本关于C++编程的书。我从书中遇到一句话:"除了不那么乏味之外,未调整大小的数组初始化方法还允许您更改任何字符串,而不必担心意外忘记调整数组大小。当我编写一些代码来测试该句子,然后在执行结束时运行代码时,我收到一个错误,指出.exe已停止工作。对于我的问题中显示的其他代码,它给出了不兼容的类型错误,即新字符串的尺寸与 char 数组的尺寸不匹配。
所以我测试了这句话,看看我对它的解释是否正确。请参阅下面的代码。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char s[] = "";
s = "Hello, my name is Mickey Mouse.";
cout << s << endl;
s = "Hello, my name is Mickey Mouse. I am 83 years old."
cout << s << endl;
}
下一个代码示例:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char s[] = "";
cout << "Enter a string" << endl;
cin.getline(s, 50);
cout << s;
cout << "How old are you" << endl;
cin.getline(s, 50);
cout << s;
}
我预计该程序会成功运行,但它崩溃了。
在第二个示例中,您将覆盖堆栈的很大一部分,这可能会崩溃,尽管未定义的行为可能会产生其他意外结果。
char s[] = "";
与char s[1] = {' '};
相同,后者只包含一个元素,即空字符。这本书只是说在这种情况下,它为你确定大小并将其复制到堆栈中。
然后,当您使用cin.getline(s, 50);
并告诉它它实际上是 50 个字符长时,它可能会写入数组的末尾并覆盖编译器放置在堆栈上的其他内容,从而导致损坏。
通常,对于getline
(如果您确实有一个堆栈分配的数组)之类的事情,可以使用sizeof
以安全的方式确定大小,以适应将来的更改。
cin.getline(s, sizeof(s));
但在C++中,几乎总是最好对字符串使用std::string
,std::vector
用于动态大小的数组,或者std::array
用于固定大小的数组。除了直接支持更多功能外,它们还可以处理内存管理,并更容易避免许多常见错误。
std::string line;
std::getline(std::cin, line);
相关文章:
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在函数内部的声明中初始化数组,并在外部使用它
- 为什么用结构初始化数组需要指定结构名称
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- C++使用另一个数组和新值初始化数组
- 初始化数组、"memset"或" {//value} "的最佳方法是什么?
- 在 constexpr 构造函数中初始化数组是否合法?
- 我可以初始化 const 实例,以便我可以将其用作 const 来初始化数组吗?
- 在构造函数中初始化数组
- 是否可以使用函数返回的值初始化数组
- 使用宏使用额外元素初始化数组
- 在循环中显示不同值的初始化数组
- 如何在macOS中的旧扩展clang和gcc编译器中初始化数组和向量
- 使用可变模板列表初始化数组,并放置new
- 使用函数从 Visual Studio 2017 中的 main 创建和初始化数组
- 使用 c++ 中的函数初始化数组
- 这是使用构造函数初始化数组对象的最佳方法吗?
- C++ 使用变量而不是常量表达式初始化数组
- 在初始化列表中初始化数组的更好方法
- 在可变参数模板类中初始化数组