在循环中执行移位操作时C ++中的内存泄漏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在循环中执行移位操作时C ++中的内存泄漏相关的知识,希望对你有一定的参考价值。

我设法将问题减少到以下代码,当它在我的笔记本电脑上运行时使用几乎500MB的内存 - 这反过来导致整个程序中的std :: bad_alloc。这里有什么问题?据我所知,无序映射只使用类似(32 + 32)* 4096 * 4096位= 134.2MB的内容,这甚至不接近程序使用的内容。

#include<iostream>
#include<unordered_map>

using namespace std;

int main()
{
    unordered_map<int,int> a;
    long long z = 0;

    for (int x = 0; x < 4096; x++)
    {
        for (int y = 0; y < 4096; y++)
        {
            z = 0;

            for (int j = 0; j < 4; j++)
            {
                    z ^= ((x>>(3*j))%8)<<(3*j);
                    z ^= ((y>>(3*j))%8)<<(3*j + 12);
            }

        a[z]++;
        }
    }
    return 0;
}

编辑:我知道这里的一些位移会导致未定义的行为,但我99%肯定这不是什么问题。

编辑2:我需要的是基本上计算给定集合中的x的数量,其中某个函数映射到第二组(大小为4096 * 4096)中的每个y。将这些数字存储在数组中会更好吗?即我有一个函数f:A到B,我需要知道B中每个y的集合{x在A:f(x)= y}中的大小。在这种情况下,A和B都是一组非负整数小于2 ^ 12 = 4096。 (理想情况下,我想将此扩展到2 ^ 32)。

答案

...它使用了近500MB的内存......这里有什么问题?

关于您正在观察的内存使用情况,本身并没有什么问题。 std::unordered_map可以快速运行大量元素。因此,内存不是首要任务。例如,为了优化调整大小,它通常在创建时为某些预先计算的hash chains分配。此外,您对元素数量乘以元素大小的度量不考虑此映射中每个节点的实际内存占用量(数据结构) - 这至少应包含指向相邻元素的几个指针in the list of its bucket

话虽如此,你还不清楚在这种情况下甚至需要使用std::unorderd_map。相反,给定映射您的尝试存储被定义为

对于B中的每个y,{x在A:f(x)= y}中

你可以拥有一个固定大小的数组(使用std::array),它只能容纳每个索引i,表示集合B中的元素,即满足条件的集合A中的元素数量。

以上是关于在循环中执行移位操作时C ++中的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

将内存泄漏检查集成到 C 代码中以进行自动分级

避免使用promises中的内存泄漏并在咖啡脚本中循环(无需等待)

java在循环语句的执行语句赋予变量值循环结束后会释放吗?

c语言 内存,可执行文件

C 语言内存四区原理 ( 内存四区建立流程 )

深入理解C