c++ - compact vector 一个小的内存足印 vector

标签 c++ memory-management stl vector

我维护着一个旧的 C++ 应用程序,它有很多如下类:

    class ClassWithALotOfVectors
    {
        std::vector<int> _vector1;
        std::vector<int> _vector2;

        // a lot of other vector datamembers go here

        std::vector<double> _vectorN;
    };

那是一种数据类型,其中成员是 double 或整型 vector 。 问题是 - 这些 vector 永远不会同时填充 - 因此 当我们创建 100000 个 ClassWithALotOfVectors 实例时 - 内存使用量加起来 尽管这些载体中只有 10% 在使用,但数量惊人。

所以我决定写一个小的“按需分配” vector 类。

它是 std::vector 的包装器——其中内部 vector 仅在以下情况下创建 第一次访问(使用两个 getters - ref() 和 const_ref() 方法)

当我用 compact_vector 替换 ClassWithALotOfVectors 类中的 std::vector 时 如下:

    class ClassWithALotOfVectors2
    {
    compact_vector<int> _vector1;
    compact_vector<int> _vector2;

    compact_vector<double> _vectorN;
    };

做了一些测试,结果很有希望——内存使用率下降了 戏剧性的,却突然发现应用程序不释放内存 最后 - 内存消耗的增长速度比它慢得多 曾经是 - 但应用程序似乎没有释放内存 在最后。

你能看看我对 compact_vector 的实现吗 看看你是否能发现内存管理的问题。

    template <class T> class compact_vector 
    { 
    public: 
            compact_vector<T>()
            :_data(NULL) 
            { 
            } 

            ~compact_vector<T>() 
            { 
                    clear(); 
            } 

            compact_vector<T>(const compact_vector<T> & rhs) 
            :_data(NULL) 
            { 
                    if (NULL != rhs._data) 
                    { 
                            _data = new std::vector<T>(*(rhs._data)); 
                    } 
                    else 
                    { 
                            clear(); 
                    } 
            } 

            //      assignment 
            // 
            compact_vector<T> & operator=(const compact_vector<T> & rhs) 
            { 
                    if (this != &rhs) 
                    { 
                            clear(); 
                            if (NULL != rhs._data) 
                            { 
                                    _data = new std::vector<T>(*rhs._data); 
                            } 
                    } 
                    return *this; 
            } 
            compact_vector<T> & operator=(const std::vector<T> & rhs) 
            { 
                    clear(); 
                    if (!rhs.empty()) 
                    { 
                            _data = new std::vector<T>(rhs); 
                    } 
                    return *this; 
            } 

            const std::vector<T> & const_ref() 
            { 
                    createInternal(); 
                    return *_data; 
            } 
            std::vector<T> & ref() 
            { 
                    createInternal(); 
                    return *_data; 
            } 
            void    clear() 
            { 
                    if (NULL != _data) 
                    { 
                            _data->clear(); 
                            delete _data; 
                            _data = NULL; 
                    } 
            } 
    private: 
            void    createInternal() 
            { 
                    if (NULL == _data) 
                    { 
                            _data = new std::vector<T>(); 
                    } 
            } 

    private: 
            compact_vector<T>(const std::vector<T> & rhs) 
            { 
            } 
            compact_vector<T>(std::vector<T> & rhs) 
            { 
            } 
            compact_vector<T>(std::vector<T> rhs) 
            { 
            } 

            std::vector<T> * _data; 
    }; 

最佳答案

std::vector 的大多数实现在需要之前不要获取内存,并且 vector 的大小通常只是几个(3 + 可能是额外的调试信息)指针。即 std::vector<int>()不会为任何对象分配空间。我相信您在这里对着错误的树吠叫。

为什么您的原始代码使用的内存要高得多?你期待吗clear()释放内存?

如果是这样你就错了。 clear()函数销毁包含的元素但不释放分配的内存。考虑添加一个包装器来清除使用以下习惯用法的内存:

std::vector<int>().swap( _data );

上一行所做的是创建一个新的 vector (通常没有附加内存,不是强制的,而是常见的实现)并交换两个 vector 的内容。在表达式的末尾,临时文件包含最初由 _data 保存的数据。 vector 和 _data是空的,没有内存(实现定义)。临时变量在完整表达式结束时被破坏,内存被释放。

或者,如果您的编译器支持 C++11,您可以使用 shrink_to_fit()打电话后 clear() .该标准不需要 shrink_to_fit()实际上缩小以适合,但对于空 vector ,我希望实现能够做到这一点。通过调用 capacity() 对其进行测试通话结束后,看看它是否下降到 0。

关于c++ - compact vector 一个小的内存足印 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9768980/

相关文章:

c++ - 全局模式匹配的递归解决方案

c++ - 我可以用c++中的istream读取二进制数据吗?

c++ - 当参数未知时如何传递函数指针

c++ - 使用相同的代码遍历STL序列和关联容器?

c++ - 在 C/C++ 中实现 JSON RESTful 服务的方法

c++ - 如果将 delete[] 应用于非数组指针会发生什么?

c - 地址加 `int`导致int加4次

c++ - QMenu 中 QAction 的所有权

c++ - 我们需要 unary_function 和 binary_function 做什么?

c++ - 迭代 std::deque 时出现奇怪的运行时错误