我对以下答案至少感兴趣:
int n;
...
std::vector<void*> vectorOfPointers;
vectorOfPointers.reserve(n);
上述程序在 O(1)中运行的数字 n 是多少?
让我们假设一台笔记本电脑运行32位Ubuntu,内存为3 GB,没有运行任何其他程序。几万,几千,几百万?为了能够评估这样的问题,需要了解哪些信息?有没有办法在不进行任何实验的情况下找到答案?
我从未研究过有关操作系统的任何内容,但在我的想象中,操作系统只需两步即可分配内存。它确定了启动块的指针和块结尾的指针。情况可能更复杂,因为系统可能必须整理以获得足够大的内存块。但是,如果我们假设系统只运行这个程序,我们如何估计所需的时间?除了记忆碎片之外还有其他一些方面需要考虑吗?
编辑:
抱歉,我没有说清楚我的问题。重要的是要考虑,在调用reserve之前向量是空的,因此不需要复制数据。答案 0 :(得分:2)
使用reserve()
时,您不能依赖O(1)的复杂性。
复杂性
容器大小的线性
(cf cppreference)
基本上,新内存的分配是恒定的,但你还需要将旧元素从前一个内存复制到新内存中(因此线性复杂度)。
所以在空向量上,保留可能会有一个恒定的时间,但我不确定该标准是否明确表示它。所以它可能取决于底层实现(即使我没有看到任何理由不这样做)。
答案 1 :(得分:2)
从C ++的角度来看,代码需要O(1)
时间(在容器的当前大小中是线性的,在您的情况下总是为零)。
现在,您的问题似乎与分配m
字节内存的复杂性有关。我恐怕没有具体说明。
有关进一步的讨论,请参阅Time complexity of memory allocation
要添加到另一个问题中已经说过的内容,有几层复杂性:
malloc()
需要维护其内部数据结构。没有指定执行此操作的复杂性,但人们希望malloc(m)
不会花费Θ(m)
时间。但是,复杂性很可能取决于其他因素,例如内存碎片。malloc()
可能需要从操作系统请求额外的内存。在这里,期望操作系统对它分配的每个内存页面执行某些操作并不是不合理的(例如擦除它以便您不会看到其他人的机密数据)。如果发生这种情况,那么操作确实是Θ(m)
。答案 2 :(得分:1)
我能想到O(1)
的唯一std::vector::reserve()
是n <= capacity()
,这意味着reserve()
什么都不做。