c++ - C++ 向量如何不使用默认构造函数在内存空间中覆盖?
问题描述
这更像是一个理论问题而不是一个问题。
据我了解,std::vector 将在添加、删除或构造时动态调整内存大小/重新分配内存。
我有几个关于向量如何在最低级别工作的问题,使用下面的代码示例
是什么阻止了以下示例覆盖的内存空间
string1
?向量是否以与数组相同的方式连续?
如果一个向量需要一个可用的总内存,但它不是连续的,它是否会对内存空间进行碎片整理?
#include <vector>
using namespace std;
int main(){
string string1 = "Some really large string";
/* A bunch of other random declarations take place
...
*/
vector<int> vector1;
for(int i = 0; i < 10; i++)
{
vector1.push_back(i);
}
}
解决方案
这些答案如何?
操作系统会(或任何处理您的内存分配的人)。通常向量和字符串的默认分配器调用操作系统在堆上分配内存。(非常小的字符串可能会与“小字符串优化,< ~16byte 字符串一起进入堆栈)。操作系统确保这些不会发生冲突。
是的,标准保证向量的连续内存。
不,它将请求它需要的大小块,并且操作系统(或任何分配器)将提供一个或失败。碎片整理是一项操作系统任务。
编辑:@parktomatomi 说的是正确的。std::vector<T>
首先为 8 个元素分配足够的内存,然后在第 9 个元素中,他们将重新请求 16 个元素,复制所有内容并释放 8 个元素块。在 32 个元素处再次相同,等等。边界取决于实现,但它是一些东西像那样。您可以使用std::vector.reserve()
来避免重新分配和复制过程。如果您有完美的信息,通常才值得,否则只需将其留给加倍算法通常就可以了。
std::array<T, N>
与原始类型(int、double 等)一样,是固定大小和堆栈分配的。所以它的大小受到堆栈的限制。
Stack 也不会破坏(显然),因为它在每个变量声明中“将堆栈指针向下移动到新空间”。
现代桌面/服务器机器上的典型堆栈大小在 linux/OSX 上为 8MB,在 Windows 上为 1MB。这些都可以调整。堆大小(向量所在的位置)仅受机器中的物理内存(如果您不介意交换到磁盘,实际上是虚拟内存)的限制。所以通常是几个 GB。
这不是一篇关于这个主题的坏文章。https://www.tutorialspoint.com/cplusplus/cpp_dynamic_memory.htm
但请注意,它谈了很多关于new
和的内容delete
。99% 的时间你不应该使用这些。它们将在构造函数和析构函数的实现中“自动”发生std::vector
(以及更多的地方)。
推荐阅读
- android - 安卓 | 简单日期格式 | 字符串到日期 | 嗯,年年
- html - 有没有办法可以只使用 HTML/CSS 放大带有链接标签的任何文本/图片?
- ios - iphone 12 mini 的导航栏背景图像着色不正确
- reactjs - 变量不从函数返回。(参考错误:找不到变量:list2)
- python-3.x - python - 将df转换为时间序列
- elasticsearch - 如何为 APM 代理配置堆配置
- python-3.x - Plotly Dash 访问控制
- http-status-codes - 什么状态码代表: POST 编辑失败,因为条目太多?
- sql - GROUP BY ID 并选择 MAX
- node.js - 从文件读取时重音字符中断