如何将std::vector的容量限制为元素的数量

How to limit the capacity of std::vector to the number of element

本文关键字:元素 容量 std vector      更新时间:2023-10-16

我的程序使用569MB的内存,只需要使用500MB,我有很多大小不同的std::矢量有没有办法将容量设置为元素的数量,以避免内存开销。(我不考虑性能,内存是关键)

如何将std::vector的容量限制为元素的数量

您能做的最好的事情就是在添加元素之前保留所需的空间。这也应该有最好的性能,因为没有重新分配和复制造成的

如果这不实用,则可以在添加元素后使用std::vector::shrink_to_fit()。当然,如果分配可能永远不会超过设定的上限,那也无济于事。

从技术上讲,这两种方法都不能保证容量与大小相匹配。您依赖于标准库实现的行为。

在向其推送任何内容之前,编写一些包装器并控制向量的大小,或者使用固定大小的std::array代替

您可能正在寻找shrink_to_fit方法,请参阅http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit.

或者,如果您不能/不被允许使用C++11,您可能需要使用swap-to-fit习惯用法:https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Shrink-以适应

在C++11中(注意编译器可能会忽略shrink_to_fit):

vector<int> v;
// ... 
v.shrink_to_fit();

换装习惯用法:

vector<int> v;
// ...
vector<int>( v ).swap(v);
// v is swapped with its temporary copy, which is capacity optimal

您可以使用自定义分配器并将所需的容量提供给模板参数。从该线程修改示例:定制C++分配器的令人信服的例子?

#include <memory>
#include <iostream>
#include <vector>
namespace my_allocator_namespace
{
    template <typename T, size_t capacity_limit>
    class my_allocator: public std::allocator<T>
    {
    public:
        typedef size_t size_type;
        typedef T* pointer;
        typedef const T* const_pointer;
        template<typename _Tp1 >
        struct rebind
        {
            typedef my_allocator<_Tp1 , capacity_limit> other;
        };
        pointer allocate(size_type n, const void *hint=0)
        {
            if( n  > capacity_limit ) {
                return std::allocator<T>::allocate(capacity_limit ); 
            }
            return std::allocator<T>::allocate(n, hint);
        }
        void deallocate(pointer p, size_type n)
        {
            return std::allocator<T>::deallocate(p, n);
        }
        my_allocator() throw(): std::allocator<T>() {  }
        my_allocator(const my_allocator &a) throw(): std::allocator<T>(a) { }
        template <class U,size_t N>                    
        my_allocator(const my_allocator<U,N> &a) throw(): std::allocator<T>(a) { }
        ~my_allocator() throw() { }
    };
}
using namespace std;
using namespace my_allocator_namespace;
int main(){
vector<int, my_allocator<int,20> > int_vec(10);
    for(int i = 0 ;i < 20; i++)
    {
        std::cerr << i << "," << int_vec.size() << std::endl;
        int_vec.push_back(i);
    }
}

但是,访问超出范围的索引时应谨慎