Is there a max array length limit in C++?

后端 未结 12 1508
深忆病人
深忆病人 2020-11-22 07:21

Is there a max length for an array in C++?

Is it a C++ limit or does it depend on my machine? Is it tweakable? Does it depend on the type the array is made of?

12条回答
  •  清酒与你
    2020-11-22 08:17

    I'm surprised the max_size() member function of std::vector has not been mentioned here.

    "Returns the maximum number of elements the container is able to hold due to system or library implementation limitations, i.e. std::distance(begin(), end()) for the largest container."

    We know that std::vector is implemented as a dynamic array underneath the hood, so max_size() should give a very close approximation of the maximum length of a dynamic array on your machine.

    The following program builds a table of approximate maximum array length for various data types.

    #include 
    #include 
    #include 
    #include 
    
    template 
    std::string mx(T e) {
        std::vector v;
        return std::to_string(v.max_size());
    }
    
    std::size_t maxColWidth(std::vector v) {
        std::size_t maxWidth = 0;
    
        for (const auto &s: v)
            if (s.length() > maxWidth)
                maxWidth = s.length();
    
        // Add 2 for space on each side
        return maxWidth + 2;
    }
    
    constexpr long double maxStdSize_t = std::numeric_limits::max();
    
    // cs stands for compared to std::size_t
    template 
    std::string cs(T e) {
        std::vector v;
        long double maxSize = v.max_size();
        long double quotient = maxStdSize_t / maxSize;
        return std::to_string(quotient);
    }
    
    int main() {
        bool v0 = 0;
        char v1 = 0;
    
        int8_t v2 = 0;
        int16_t v3 = 0;
        int32_t v4 = 0;
        int64_t v5 = 0;
    
        uint8_t v6 = 0;
        uint16_t v7 = 0;
        uint32_t v8 = 0;
        uint64_t v9 = 0;
    
        std::size_t v10 = 0;
        double v11 = 0;
        long double v12 = 0;
    
        std::vector types = {"data types", "bool", "char", "int8_t", "int16_t",
                                          "int32_t", "int64_t", "uint8_t", "uint16_t",
                                          "uint32_t", "uint64_t", "size_t", "double",
                                          "long double"};
    
        std::vector sizes = {"approx max array length", mx(v0), mx(v1), mx(v2),
                                          mx(v3), mx(v4), mx(v5), mx(v6), mx(v7), mx(v8),
                                          mx(v9), mx(v10), mx(v11), mx(v12)};
    
        std::vector quotients = {"max std::size_t / max array size", cs(v0),
                                              cs(v1), cs(v2), cs(v3), cs(v4), cs(v5), cs(v6),
                                              cs(v7), cs(v8), cs(v9), cs(v10), cs(v11), cs(v12)};
    
        std::size_t max1 = maxColWidth(types);
        std::size_t max2 = maxColWidth(sizes);
        std::size_t max3 = maxColWidth(quotients);
    
        for (std::size_t i = 0; i < types.size(); ++i) {
            while (types[i].length() < (max1 - 1)) {
                types[i] = " " + types[i];
            }
    
            types[i] += " ";
    
            for  (int j = 0; sizes[i].length() < max2; ++j)
                sizes[i] = (j % 2 == 0) ? " " + sizes[i] : sizes[i] + " ";
    
            for  (int j = 0; quotients[i].length() < max3; ++j)
                quotients[i] = (j % 2 == 0) ? " " + quotients[i] : quotients[i] + " ";
    
            std::cout << "|" << types[i] << "|" << sizes[i] << "|" << quotients[i] << "|\n";
        }
    
        std::cout << std::endl;
    
        std::cout << "N.B. max std::size_t is: " <<
            std::numeric_limits::max() << std::endl;
    
        return 0;
    }
    

    On my macOS (clang version 5.0.1), I get the following:

    |  data types | approx max array length | max std::size_t / max array size |
    |        bool |   9223372036854775807   |             2.000000             |
    |        char |   9223372036854775807   |             2.000000             |
    |      int8_t |   9223372036854775807   |             2.000000             |
    |     int16_t |   9223372036854775807   |             2.000000             |
    |     int32_t |   4611686018427387903   |             4.000000             |
    |     int64_t |   2305843009213693951   |             8.000000             |
    |     uint8_t |   9223372036854775807   |             2.000000             |
    |    uint16_t |   9223372036854775807   |             2.000000             |
    |    uint32_t |   4611686018427387903   |             4.000000             |
    |    uint64_t |   2305843009213693951   |             8.000000             |
    |      size_t |   2305843009213693951   |             8.000000             |
    |      double |   2305843009213693951   |             8.000000             |
    | long double |   1152921504606846975   |             16.000000            |
    
    N.B. max std::size_t is: 18446744073709551615
    

    On ideone gcc 8.3 I get:

    |  data types | approx max array length | max std::size_t / max array size |
    |        bool |   9223372036854775744   |             2.000000             |
    |        char |   18446744073709551615  |             1.000000             |
    |      int8_t |   18446744073709551615  |             1.000000             |
    |     int16_t |   9223372036854775807   |             2.000000             |
    |     int32_t |   4611686018427387903   |             4.000000             |
    |     int64_t |   2305843009213693951   |             8.000000             |
    |     uint8_t |   18446744073709551615  |             1.000000             |
    |    uint16_t |   9223372036854775807   |             2.000000             |
    |    uint32_t |   4611686018427387903   |             4.000000             |
    |    uint64_t |   2305843009213693951   |             8.000000             |
    |      size_t |   2305843009213693951   |             8.000000             |
    |      double |   2305843009213693951   |             8.000000             |
    | long double |   1152921504606846975   |             16.000000            |
    
    N.B. max std::size_t is: 18446744073709551615
    

    It should be noted that this is a theoretical limit and that on most computers, you will run out of memory far before you reach this limit. For example, we see that for type char on gcc, the maximum number of elements is equal to the max of std::size_t. Trying this, we get the error:

    prog.cpp: In function ‘int main()’:
    prog.cpp:5:61: error: size of array is too large
      char* a1 = new char[std::numeric_limits::max()];
    

    Lastly, as @MartinYork points out, for static arrays the maximum size is limited by the size of your stack.

提交回复
热议问题