Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does max_size() of std::vector<char> have a bug?

Tags:

c++

vector

I am puzzled by the result of std::vector< char >::max_size() on the n = 32 and n = 64 bits system I have tested. The result is 2n − 1. Let me explain why I am puzzled.

Every implementation of std::vector<T> that I know of has three members of type T*: begin_, end_, capacity_.

begin_ points to the first value of the vector and end_ points to the one after the last. Therefore, the size of the vector is given by end_ - begin_. But the result of this difference is of type std::ptrdiff_t which is a signed integer of n bits on every implementation that I know of.

Therefore, this type can not store 2n − 1, but only up to 2n − 1 − 1. If you look at your std::vector implementation, you'll clearly see that size makes a difference of 2 pointers (before casting it to an unsigned integer).

So, how come they can pretend to store more than 2n − 1 elements without breaking .size()?

like image 545
InsideLoop Avatar asked Feb 14 '15 14:02

InsideLoop


1 Answers

It is obviously a bug in some standard library implementations. I have done more work on that subject and, using the following code

#include <iostream>
#include <climits>
#include <vector>

int main() {
    auto v = std::vector<char>();
    std::cout << "Maximum size of a std::vector<char>: " <<
            v.max_size() << std::endl;
    std::cout << "Maximum value a std::size_t can hold: " <<
            SIZE_MAX << std::endl;
    std::cout << "Maximum value a std::ptrdiff_t can hold: " <<
            PTRDIFF_MAX << std::endl;

    return 0;
}

one can easily show that:

  1. in libc++, used by clang, max_size() returns PTRDIFF_MAX
  2. in libstdc++ used by gcc 4.9.2, max_size() returns SIZE_MAX
  3. in the Visual Studio 2013 implementation, max_size() returns SIZE_MAX

Therefore, libstdc++ and the Microsoft implementation of the standard library have the bug but libc++ does not have it. I'll fill a bug report against those 2.

  • Gcc. Reported as bug 65131. It has been rejected as the ABI says for all 32 bit ABIs you cannot allocate more than half the address space. This problem has been previously addressed here: https://gcc.gnu.org/ml/gcc/2011-08/msg00221.html
like image 88
InsideLoop Avatar answered Oct 12 '22 00:10

InsideLoop