我有以下代码:
#include <iostream>`
using namespace std;
int main() {
char* data = new char;
cin >> data;
cout << data << endl;
return 1;
}
当我输入char*
26 个作为字符串文字时,它会编译并打印它。但是当我将 27 个作为数据时,它会中止。我想知道为什么。
为什么是27?
它对它有什么特殊意义吗?
你只分配了一个角色的空间。因此,读取任何超过该数据的数据都会覆盖您不拥有的内存,因此这是未定义的行为。这就是您在结果中看到的。
您动态分配一个字节的存储空间。要分配倍数,请执行以下操作:
char* data = new char[how_many_bytes];
当您使用字符串文字时,会自动分配那么多堆栈空间。当你动态分配时,你必须得到正确的字节数,否则你会得到一个段错误。
这只是未定义的行为,又名“UB”。该程序可以做任何事情或不做任何事情。您看到的任何效果都是不可重现的。
为什么是UB?
因为您为单个char
值分配空间,并将其视为以零结尾的字符串。由于零占用一个char
值,因此没有(保证)真实数据的空间。但是,由于 C++ 实现通常不会增加对事物的低效检查,因此您可以将数据存储在您不拥有的部分内存中 - 直到由于 UB 而崩溃或产生无效结果或产生其他不良影响。
要正确执行此操作,请使用std::string
代替char*
,不要使用new
或delete
(astd::string
会自动为您执行此操作)。
然后用于std::getline
将一行输入读入字符串。
您必须查看 C++ 实现的具体细节。大概是执行malloc
,等等。您的代码写入缓冲区的末尾,根据 C++ 标准,该缓冲区是 UB。要完全了解它为何如此行事,您需要知道应该存储在您覆盖的 27 或 28 个字节中的内容,这是您不应该做的。
Most likely, 27 ones just so happens to be the point at which you started damaging the data structures used by the memory allocator to track allocated and free blocks. But with UB you might find that the behavior isn't as consistent as it first appears. As a C++ programmer you aren't really "entitled" to know about such details, because if you knew about them then you might start relying on them, and then they might change without notice.