以字节为单位计算向量矢量的大小

时间:2016-03-29 01:59:51

标签: c++ sizeof

typedef vector<vector<short>> Mshort;
typedef vector<vector<int>> Mint;

Mshort mshort(1 << 20, vector<short>(20, -1)); // Xcode shows 73MB 
Mint mint(1 << 20, vector<int>(20, -1)); // Xcode shows 105MB

short使用2个字节和int 4个字节;请注意1 << 20 = 2^20;

我正在尝试提前计算(在纸面上)内存的使用情况,但我无法做到。

sizeof(vector<>) // = 24 //no matter what type
sizeof(int) // = 4
sizeof(short) // = 2

我不明白:mint应该是mshort的两倍,但事实并非如此。仅在mshort初始化时运行程序 Xcode显示73MB的内存使用量; mint 105MB ;

mshort.size() * mshort[0].size() * sizeof(short) * sizeof(vector<short>) // = 1006632960
mint.size() * min[0].size() * sizeof(int) * sizeof(vector<int>) // = 2013265920

//no need to use .capacity() because I fill vectors with -1
1006632960 * 2 = 2013265920

如何计算2d std::vector使用或2d std::array使用的RAM空间大小。

我知道前面的尺寸,每行有相同的列数。

3 个答案:

答案 0 :(得分:2)

矢量矢量的内存使用量将是例如。

// the size of the data...
mshort.size() * mshort[0].size() * sizeof(short) +

// the size of the inner vector objects...
mshort.size() * sizeof mshort[0] +

// the size of the outer vector object...
// (this is ostensibly on the stack, given your code)
sizeof mshort +

// dynamic allocation overheads
overheads

动态分配开销是因为vector内部new内存用于他们要存储的元素,并且出于速度原因,他们可能有固定大小的内存区域池等待新请求,所以如果vector有效地执行new short[20] - 数据需要40个字节 - 它可能会以例如实现可能实际上需要使用一些额外的内存来存储数组大小,但是对于shortint,在{{{{}}期间不需要循环调用析构函数的元素。{48}。 1}},所以一个好的实现将避免分配和无操作破坏行为。

任何给定向量的实际数据元素在内存中都是连续的,因此如果要减少开销,可以将代码更改为使用更少,更大的delete[]。例如,使用一个vectorvector的开销可以忽略不计 - 然后您可以编写一个包含{{1}的简单类,而不是访问(1 << 20) * 20[i][j]为你做这件事,最简单的是用[i * 20 + j]表示法......

vector

...虽然您可以通过让v(i, j)返回可以使用inline short& operator()(size_t i, size_t j) { return v_[i * 20 + j]; } inline short operator()(size_t i, size_t j) const { return v_[i * 20 + j]; } 进一步编入索引的代理对象来支持v[i][j]。我确定如果您在SO上搜索有关多维数组的问题,那么就会有一些例子 - 我想我可能已经发布了一次这样的代码。

想要v.operator[]的主要原因是内部[]的长度不同。

答案 1 :(得分:2)

假设glibc malloc: 每个内存块将为内存块头分配额外的8-16个字节(2 size_t)。对于64位系统,它将是16个字节。 看代码: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1110

chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |             Size of previous chunk, if allocated            | |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |             Size of chunk, in bytes                       |M|P|
  mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |             User data starts here...                          .
    .                                                               .
    .             (malloc_usable_size() bytes)                      .
    .                                                               |

当每行添加16个字节时,它给出了大约83886080.

26 + 16 + mshort.size(1048576)*(mshort [0] .size(20)* sizeof(short(2))+ sizeof(vector(26))+ header(16))

它为int提供了大约125829120。

然后我重新计算你的数字,看起来你是32位......

  • 短75497472即~73M
  • 长117440512即~112M

看起来非常接近报道的内容。

使用容量而不是大小来获取#items编号,即使在您的情况下它们是相同的。

分配单个矢量大小的行*列将保存标题* 1048576字节。

答案 2 :(得分:2)

您的计算mshort.size() * mshort[0].size() * sizeof(short) * sizeof(vector<short>) // = 1006632960完全错误。根据您的计算,mshort需要1006632960,即960MiB,这是不正确的。

让我们忽略libc的开销,只关注std::vector<>的大小: mshortvector1^20个项目,每个项目vector<short>有20个项目。 因此大小应为:

mshort.size() * mshort[0].size() * sizeof(short) // Size of all short values + mshort.size() * sizeof(vector<short>) // Size of 1^20 vector<short> + sizeof(mshort) // Size of mshort itself, which can be ignored as overhead

计算出的尺寸 64MiB

与薄荷相同,其中计算出的尺寸 104MiB

所以mint只是 mshort的双倍大小。