我有以下代码:
#include <iostream>`
using namespace std;
int main() {
char* data = new char;
cin >> data;
cout << data << endl;
return 1;
}
当我输入26个char*
作为字符串文字时,它会编译并打印出来。但是,当我将27个数据作为数据时,它就会中止。我想知道原因。
为什么是27?
它有特殊含义吗?
答案 0 :(得分:2)
你只分配一个角色的空间。因此,读取任何数据不仅仅是覆盖您不拥有的内存,因此这是未定义的行为。这是你在结果中看到的。
答案 1 :(得分:0)
您动态分配一个字节的存储空间。要分配倍数,请执行以下操作:
char* data = new char[how_many_bytes];
使用字符串文字时,会自动分配多个堆栈空间。当你动态分配时,你必须得到正确的字节数,否则你将得到一个段错误。
答案 2 :(得分:0)
这只是未定义的行为,a.k.a。“UB”。该计划可以做任何事情或什么都不做您看到的任何效果都是不可复制的。
为什么是UB?
因为您为单个char
值分配空间,并将其视为以零结尾的字符串。由于零占用一个char
值,因此没有(保证)空间用于实际数据。但是,由于C ++实现通常不会添加低效的事物检查,因此您可以放弃将数据存储在您不拥有的内存部分中 - 直到它崩溃或产生无效结果或由于UB而产生其他不良影响。
要正确执行此操作,请使用std::string
代替char*
,而不是new
或delete
(std::string
会自动为您执行此操作)
然后使用std::getline
将一行输入读入字符串。
答案 3 :(得分:0)
您必须在C ++实现的底层查看具体细节。可能是malloc
的实现,等等。您的代码写入缓冲区的末尾,根据C ++标准,它是UB。要想知道为什么它的行为就像它一样,你需要知道应该存储在你覆盖的27或28个字节中的内容,你不应该这样做。
最有可能的是,27个恰好是您开始破坏内存分配器用于跟踪已分配和空闲块的数据结构的点。但是对于UB,您可能会发现行为不像第一次出现那样一致。作为一名C ++程序员,你并没有真正“有资格”了解这些细节,因为如果你了解它们,那么你可能会开始依赖它们,然后它们可能会在没有通知的情况下发生变化。