std :: allocator :: max_size()背后的基本原理是什么?

时间:2014-03-04 21:13:50

标签: c++ memory-management c++11

我知道来自max_size()的{​​{1}}是理论限制,但我只是尝试了一些东西而且我得到的数字都很大;那我该怎么解释这个数字呢?这个函数背后的哲学是什么?

我的例子:

std::allocator

打印:

#include <iostream>
#include <memory>
#include <cstdint>
typedef int8_t Tnum_1;
struct X
{
    template <typename T>
    static void printAllocInfo()
    {
        std::cout << std::allocator<T>().max_size() << "\t Alloc max_size\n";
        std::cout << ((std::allocator<T>().max_size()) / (1024))
                  << "\t Alloc max_size / 1024\n";
        std::cout << (((std::allocator<T>().max_size()) / (1024)) / (1024))
                  << "\t\t Alloc max_size / 1024 / 1024\n";
    }
};
int main()
{
    X::printAllocInfo<Tnum_1>();
    return (0);
}

并且考虑到我只使用18446744073709551615 Alloc max_size 18014398509481983 Alloc max_size / 1024 17592186044415 Alloc max_size / 1024 / 1024 作为模板参数,这意味着我可以在我的机器上分配int8_t?这个数字太大了,它开始失去任何实际意义。

3 个答案:

答案 0 :(得分:2)

你引用的那个数字当然是2 ^ 64 -1,a.k.a是可以表示的最大的64位无符号整数。所有max_size()表示它不支持任何更大的内容,而不是它支持低于该大小的所有内容。

由您的操作系统实际提供给您的程序。但是,由于您可以在运行它的其他计算机上编译程序(包括在不久的将来使用的计算机),因此没有理由将max_size()限制为较小的数字。

注意:如果您阅读了C ++标准中的表31 - 分配器要求,您会发现以下类型{{1}的分配器对象a }}:

  

X:为a.allocate(n)类型的n个对象分配内存,但是   对象不构造。

     

T:可以有意义地传递给的最大值   a.max_size()

因此X::allocate()是可以分配的最大对象数,而不是字节数。

答案 1 :(得分:2)

之前提供的答案是不完整的,因为它们只提到字节数,而不是对象数。

documentation for max_size表示函数应该返回&#34; n的理论上可能的最大值,调用allocate(n,0)可以成功,&#34; 其中n是对象的数量。它还说,对于某些分配器实现,它应该返回

std::numeric_limits<size_type>::max() / sizeof(value_type)

而不是

std::numeric_limits<size_type>::max()

STL容器(例如 - std::vectorstd::mapstd::list)使用max_size来计算容器大小,而不是字节数。因此,max_size()不应返回操作系统上可用的字节数,而是使用可用字节数来计算分配器可以容纳的对象数

如果你为STL容器编写了一个allocator类,你可以像这样实现max_size()函数来提供准确的对象计数,而不是使用std::numeric_limits<size_type>::max()进行高估。

size_type max_size() const
{
    const unsigned long long bytesAvailable = GetTotalAvailableMemory();
    const unsigned long long maxPossibleObjects = bytesAvailable / sizeof(value_type);
    return maxPossibleObjects;
}

您可以根据您的操作系统实现GetTotalAvailableMemory()这些功能。要么返回程序进程可能使用的未分配字节数。

#if defined(unix) || defined(__unix__) || defined(__unix)

#include <unistd.h>

unsigned long long GetTotalAvailableMemory()
{
    const long pageCount = sysconf( _SC_PHYS_PAGES );
    const long pageSize = sysconf( _SC_PAGE_SIZE );
    const unsigned long long totalBytes = pageCount * pageSize;
    return totalBytes;
}

#endif

#if defined(_WIN64) || defined(_WIN64)

#include <windows.h>

unsigned long long GetTotalAvailableMemory()
{
    MEMORYSTATUSEX status;
    status.dwLength = sizeof( status );
    GlobalMemoryStatusEx( &status );
    return status.ullAvailVirtual;
}

#endif

答案 2 :(得分:1)

来自http://www.cplusplus.com/reference/vector/vector/max_size/

  

由于已知的系统或库实现限制,这是容器可以达到的最大可能大小,但容器无法保证能够达到该大小:在此之前的任何时候它仍然无法分配存储达到了规模。

正如TemplateRex指出的那样,你看到的数字是2 ^ 64。基本上这是根据软件的编写方式告诉你一个理论上的限制,而不是操作系统真正尊重这么大的分配。