C++ 指针与 std::vector:对长变量有任何影响吗?
Posted
技术标签:
【中文标题】C++ 指针与 std::vector:对长变量有任何影响吗?【英文标题】:C++ pointers vs std::vector: any implication for long size variables? 【发布时间】:2020-11-17 17:42:36 【问题描述】:我有 C 背景,我正在用 C++ 重新编写一些旧代码... 在这个过程中,我开始使用 C++ Vectors,它非常好用!
向量能否很好地处理很长的数据流?例如,在音频应用中,加载一首 3 分钟的立体声歌曲需要将近 16M 的浮点数
float *stereoSong = NULL;
stereoSong = new floats[15787800];
不必用向量处理内存管理非常好,但我想知道 C++ 向量是否可以很好地处理大量数据
谢谢!
【问题讨论】:
std::vector
只是堆中的一个数组,具有大小和指向第一个元素的指针。我能想到的唯一性能问题是每次扩展时容量都会增加 2 倍。这可以通过std::vector::reserve
甚至std::vector::shrink_to_fit
来解决。
既然你已经知道C,你可以把它比作一个动态分配的数组。
您可能会惊讶地发现std::vector
只是一个指针和一个元素计数(以及一个额外的计数器)。结束。
我在这被毫不客气地关闭之前写了一个答案。这是一个 noddy 程序,它可以输出一个非常大的向量。 ideone.com/A6GmvQ。该代码甚至足够简单,不保留容量,但允许 std::vector
执行此操作。
@WewillSee 嗨。我刚刚注意到您的矢量版本pointer2[i]=pointer2[i]
中有一个错误。您已将指针 2 分配给自身。优化器忽略了整个循环。当我运行它时,尽管这不是科学测试,但矢量版本实际上更快一点!
【参考方案1】:
这是一个错误的比较。
首先,向量使用指针。他们必须。向量是使用动态分配为您提供数据项缓冲区的容器。你可以尝试“用指针”实现同样的东西,但你最终会在向量和更糟糕的向量版本之间得到某种东西。
因此,向量可以处理与new double[]
一样多的数据——也就是说,很多。
【讨论】:
【参考方案2】:答案很大程度上取决于您的平台。
您说的是超过 150 MiB 的数据(double
在几乎所有现代平台上都是 8 个字节)。
此代码在“玩具”环境中没有问题 (https://ideone.com/A6GmvQ):
#include <iostream>
#include <vector>
void build(std::vector<double>& data, const size_t size)
void* ptrdata.data();
for(size_t i1;i<=size;++i)
data.push_back(2*i);
if(data.data()!=ptr)
ptr=data.data();
std::cout << i << ' ' << ptr << ' ' << data.capacity() << std::endl;
int main()
size_t size100000000L;
std::cout << ((size*sizeof(double))/1024/1024) << " MiB" << std::endl;
std::vector<double> data;
build(data,size);
double sum0;
for(auto curr : data)
sum+=curr;
std::cout << sum << std::endl;
return 0;
这段代码明知是愚蠢的,甚至没有尝试为值保留容量(这可以提供帮助),因为std::vector<>
无论如何都可以帮助解决这个问题。
在幕后,向量分配一个容量块,然后当向量的逻辑大小超过容量时重新分配另一个更大的容量。 代码“监视”内部表示并输出每次重新分配...
如果您将值作为流使用(听起来很可能是音频),那么有成员可以帮助您进行容量管理。
简短的回答是“试一试”。我已经将它提高到 100M 双倍,没有问题。
【讨论】:
【参考方案3】:std::vector
and 公司。是我将 C
更改为 C++
的原因之一。
它将所有管理样板从数组管理中取出。
当我需要调整数组分配的大小时,我必须执行以下操作
-
分配新内存
复制元素
删除旧记忆
此外,所有生命周期管理都由 std::vector
处理,在生命周期结束时不再与 delete
搞混,这使得在一个函数中处理多个退出点变得更加容易。
【讨论】:
【参考方案4】:由于实现的限制是std::vector::max_size
。比如herestd::vector<float>::max_size()
就是2305843009213693951
。
但是,由于实施的限制,这只是理论上的限制。很快你就会达到硬件的内存限制。
std::vector<float>
不使用(基本上)比动态 c 数组更多的内存。
【讨论】:
以上是关于C++ 指针与 std::vector:对长变量有任何影响吗?的主要内容,如果未能解决你的问题,请参考以下文章