与教科书上关于未调整大小的数组初始化C++句子的混淆

Confusion with textbook sentence on unsized array initialization C++

本文关键字:初始化 数组 C++ 句子 教科书 于未 调整      更新时间:2023-10-16

我正在读一本关于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::stringstd::vector用于动态大小的数组,或者std::array用于固定大小的数组。除了直接支持更多功能外,它们还可以处理内存管理,并更容易避免许多常见错误。

std::string line;
std::getline(std::cin, line);