C++ std :: vector的行为就像在特定情况下泄漏内存一样

 手机用户2502907707 发布于 2022-12-11 20:53

我发现了一种情况,其中向量的行为类似于泄漏内存,并且可以将其归结为最小的工作示例.在这个例子中,我(在一个函数中)生成一个包含三个char向量的向量.首先,这些char矢量被推入大量元素,它们的容量缩小到它们的大小.然后在大矢量上分配单元素大小的矢量.现在的问题是,使用的内存太大,即使函数返回并且向量被破坏,内存也不会被释放.我如何获得回忆?为什么它显示这个bahaviour?我该怎么做才能避免这种泄漏行为?

这里是示例代码(抱歉长度):

#include 
#include 
#include 
#include 

using namespace std;

// see http://man7.org/linux/man-pages/man5/proc.5.html at /proc/[pid]/status
string meminfo() {
    // memory information is in lines 11 - 20 of /proc/self/status
    ifstream stat_stream("/proc/self/status",ios_base::in);

    // get VmSize from line 12
    string s;
    for ( int linenum = 0; linenum < 12; ++linenum )
        getline(stat_stream,s);
    stat_stream.close();
    return s;
}

void f() {
    vector> mem(3); // with 1,2 memory is fine
    size_t size = 16777215;      // with 16777216 or greater memory is fine
    for ( vector& v : mem ) {
        for ( unsigned int i = 0; i < size; ++i )
            v.push_back(i);
        v.shrink_to_fit();       // without this call memory is fine
    }

    cout << "Allocated vectors with capacities ";
    for ( vector& v : mem )
        cout << v.capacity() << ", ";
    cout << endl << "used memory is now:   " << meminfo() << endl;

    for ( vector& v : mem ) {
        v = vector{1};
        if ( v.size() != v.capacity() )
            cout << "Capacity larger than size." << endl;
    }
    cout << "Shrinked vectors down to capacity 1." << endl
        << "Used memory is now:   " << meminfo() << endl;
}

int main() {
    cout << "At beginning of main: " << meminfo() << endl;
    f();
    cout << "At end of main:       " << meminfo() << endl;
    return 0;
}

我机器上的输出:

At beginning of main: VmSize:      12516 kB
Allocated vectors with capacities 16777215, 16777215, 16777215,
used memory is now:   VmSize:      78060 kB
Shrinked vectors down to capacity 1.
Used memory is now:   VmSize:      61672 kB
At end of main:       VmSize:      61672 kB

但是,valgrind看不到内存泄漏.

我想这个例子中的参数是系统相关的,以显示奇怪的行为.我使用Linux Mint Debian Edition和g ++ 4.8.2以及x86_64内核.我编译:

g++ -std=c++11 -O0 -Wall memory.cpp -o memory

并尝试-O3并没有明确的优化设置.

一些有趣的观点是:

当我更换v = vector{1};v.clear(); v.shrink_to_fit(); v.push_back(1);问题保持不变.通过v = vector(16777215);"解决"内存问题来替换大矢量的推动和收缩.

16777215 = 2 ^ 24 - 1,所以也许它必须对内存边界做一些事情.

此外,人们可以期望程序在main(12516 kiB)的开头使用的存储器加上大矢量的存储器,程序应该总共使用大约3*16777216 B + 12516 kiB = 61668 kiB,这大约是它最终使用的内存.

在现实世界的应用程序中,我使用向量来收集应该应用于FEM模拟的刚度矩阵的操作.由于我想达到可用内存的可能性(也就速度而言),我需要保存不同的内存以避免交换.由于交换确实发生,我认为VmSize值是可靠的.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有