libstdc++/8230: Buggy allocator behaviour

Gabriel Dos Reis gdr@integrable-solutions.net
Thu Nov 14 06:59:00 GMT 2002


bkoz@gcc.gnu.org writes:

| Synopsis: Buggy allocator behaviour
| 
| Responsible-Changed-From-To: unassigned->bkoz
| Responsible-Changed-By: bkoz
| Responsible-Changed-When: Wed Nov 13 14:19:11 2002
| Responsible-Changed-Why:
|     Mine.
| State-Changed-From-To: open->feedback
| State-Changed-By: bkoz
| State-Changed-When: Wed Nov 13 14:19:11 2002
| State-Changed-Why:
|     I don't think this is an allocator::allocate issue per se. The member function reserve is only in std::vector and std::vector<bool>, and the standard says

Hi Benjamin,

  This issue is a conjugation of both std::allocator<> and
std::vector<> ill-behaviour.  Fixing std::vector<> fixes a part of
the problem (i.e. the testcase provided will pass), but leaves
completely unfixed the std::allocator<> bits as required by the
standard: 

20.4.1.1 allocator members

2/
  pointer allocator(size_type n, allocator<void>::const_pointer = 0);

7/
  Throws: bad_alloc if the storage cannot be obtained

20.4.1.1/11
  size_type max_size() const throw();
  returns the largest value N for which the call allocate(N, 0) might
  succeed. 

Now consider

int main()
{
   try {
      std::allocator<int> alloc;
      const std::allocator<int>::size_type n = alloc.max_size();
      int* p = alloc.allocate(n + 1);
      p[n] = 2002;
      std::cout << p[n] << std::endl;
   } catch(const std::bad_alloc& e) {
      std::cerr << e.what() << std::endl;
   }
}

This coredumps on my machine using current source.  The problem here is
that std::allocator<> is not checking the bounds as required and it is
lying.

On fr.comp.lang.c++, I developed a theory to the effect that
std::vector<> may always not check the bounds and still remain
conformant *provided* that the allocator is doing the right thing.  

|     23.2.4.2 - vector capacity
|     
|     -4- Throws: length_error if n > max_size().* 
|     
|     Where allocator::allocate doesn't know what vector::max_size is. 

Agreed.

|     
|     This fix brings the code up to conformance, and is the best fix I think.

It, however, does not address the std::allocator<> ill-behaviour.

I'm also nervous about:

   std::vector<int> v;
   v.resize(v.max_size());

   v[v.max_size() - 1] = 2002;

I didn't test it with your patch.

-- Gaby



More information about the Gcc-bugs mailing list