简体   繁体   English

默认动态内存大小

[英]Default dynamic memory size

I have the following code: 我有以下代码:

#include <iostream>`

using namespace std;
int main() {
    char* data = new char;
    cin >> data;
    cout << data << endl;
    return 1;
}

When I type in a char* of 26 ones as a string literal, it compiles and prints it. 当我输入26个char*作为字符串文字时,它会编译并打印它。 But when I do 27 ones as data, it aborts. 但是,当我将27个数据作为数据时,它就会中止。 I want to know why. 我想知道为什么。

Why is it 27? 为什么是27?

Does it have a special meaning to it? 它有特殊意义吗?

You're only allocating one character's worth of space. 你只分配一个角色的空间。 So, reading in any data more than that is overwriting memory you don't own, so that's undefined behavior. 因此,读取任何数据不仅仅是覆盖您不拥有的内存,因此这是未定义的行为。 Which is what you're seeing in the result. 这是你在结果中看到的。

Your dynamically allocating one byte of storage. 您动态分配一个字节的存储空间。 To allocate multiples, do this: 要分配倍数,请执行以下操作:

char* data = new char[how_many_bytes];

When you use a string literal, that much stack space is allocated automatically. 使用字符串文字时,会自动分配多个堆栈空间。 When you allocate dynamically, you have to get the number of bytes right or you will get a segfault. 动态分配时,必须正确获取字节数,否则会出现段错误。

This is just Undefined Behavior , aka "UB". 这只是未定义的行为 ,又名“UB”。 The program can do anything or nothing. 该计划可以做任何事情或什么都不做 Any effect you see is non-reproducable. 您看到的任何效果都是不可复制的。

Why is it UB? 为什么是UB?

Because you allocate space for a single char value, and you treat that as a zero-terminated string . 因为您为单个char值分配空间,并将其视为以零结尾的字符串 Since the zero takes up one char value there is no (guaranteed) space for real data. 由于零占用一个char值,因此没有(保证)空间用于实际数据。 However, since C++ implementations generally do not add inefficient checking of things, you can get away with storing data in parts of memory that you don't own – until it crashes or produces invalid results or has other ungood effect, because of the UB. 但是,由于C ++实现通常不会添加低效的事物检查,因此您可以放弃将数据存储在您不拥有的内存部分中 - 直到它崩溃或产生无效结果或由于UB而产生其他不良影响。

To do this correctly, use std::string instead of char* , and don't new or delete (a std::string does that automatically for you). 要正确执行此操作,请使用std::string而不是char* ,并且不要newdeletestd::string会自动为您执行此操作)。

Then use std::getline to read one line of input into the string. 然后使用std::getline将一行输入读入字符串。

You'd have to look into specific details under the hood of your C++ implementation. 您必须在C ++实现的底层查看具体细节。 Probably the implementation of malloc , and so on. 可能是malloc的实现,等等。 Your code writes past the end of your buffer, which is UB according to the C++ standard. 您的代码写入缓冲区的末尾,根据C ++标准,它是UB。 To get any idea at all of why it behaves as it does, you'd need to know what is supposed to be stored in the 27 or 28 bytes you overwrote, that you shouldn't have done. 要想知道为什么它会像它一样运行,你需要知道应该存储在你覆盖的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. 最有可能的是,27个恰好是您开始破坏内存分配器用于跟踪已分配和空闲块的数据结构的点。 But with UB you might find that the behavior isn't as consistent as it first appears. 但是对于UB,您可能会发现行为不像第一次出现那样一致。 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. 作为一名C ++程序员,你并没有真正“有资格”了解这些细节,因为如果你了解它们,那么你可能会开始依赖它们,然后它们可能会在没有通知的情况下发生变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM