3

N3485 20.6.9.1 [allocator.members]/1 says:

Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before the next allocation (if any) in this order.

This last requirement confuses me. It looks like the standard is saying that if one allocates a block of memory (let's call it block a), and then allocates another block (let's call it block b), then it is not allowed to deallocate block a until it has deallocated block b.

If this is indeed what this paragraph entails, I don't see how one could implement something like vector's growing in a space efficient manner; because one couldn't allocate a bigger buffer and then deallocate the previously allocated (too small) buffer.

Is this actually what this paragraph means, or am I misreading this section?

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552

1 Answers1

2

Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before the next allocation (if any) in this order.

From what it seems to me, it only establishes a happens-before relationship between allocations and deallocations (to prevent concurrency issues arising from incorrect compiler optimisations, possibly). It definitely does not establish a relationship between a and b where a and b are different allocated regions.

Remember that compilers follow the specification, not human logic. The specification aids the compiler programmers remember all the details that need to be taken care of (if it follows specification, it's correct). This is why the specification contains details that one would consider obvious. One of the details is that the deallocation/allocation constitutes a memory barrier.

Compare

reads -> deallocation -> allocation -> writes

with

reads -> deallocation
allocation -> writes

Without a happens-before relationship, two threads may use the same memory region (unit of storage) concurrently, as observed by the memory region. With a happens-before relationship, all access from the deallocating thread must be flushed before the allocating thread gets to use it.

John Dvorak
  • 26,799
  • 13
  • 69
  • 83
  • +1 -- Oh, could the intent be that you can't call `allocate` on two different threads and get the same pointer back in both? – Billy ONeal Dec 09 '12 at 08:14
  • @BillyONeal remember that compilers follow the specification, not human logic. The specification aids the compiler programmers remember all the details that need to be taken care of (if it follows specification, it's correct). – John Dvorak Dec 09 '12 at 08:17
  • 1
    I don't understand what you mean by that comment in relation to this answer/question/comment. Yes, compilers follow the spec; but humans implement the compiler so humans (and in this case, me) need to understand what is going on in order to follow the spec correctly. One needs to understand what is going on here in order to write a conformant allocator or allocator-aware container. – Billy ONeal Dec 09 '12 at 08:20
  • I believe the intent is to prevent concurrency issues arising from delaying one thread's deallocation (which is just a memory write) past the other thread's allocation. – John Dvorak Dec 09 '12 at 08:37
  • @JohnDvorak If the deallocation is "delayed", how can an allocation occur? – curiousguy May 28 '19 at 14:07
  • @curiousguy If the thread calls the allocator to release some memory, but then uses that memory as if it hadn't, it will clash with some other thread that has managed to grab the same memory chunk in the meantime. So you need a specification that forbids the compiler from doing exactly that by telling the thread the deallocation hasn't happened yet. – John Dvorak May 28 '19 at 15:02
  • @JohnDvorak Maybe... I still intuitively think it's the allocator's business to provide the appropriate guarantee and it shouldn't have to be written at all. – curiousguy May 28 '19 at 19:22
  • @curiousguy the allocator behavior (that allocations don't overlap) sounds like stuff that belongs to the specification - and thus has to be written down. Otherwise you couldn't rely on it. – John Dvorak May 28 '19 at 20:01
  • @JohnDvorak Why does the specification even use a thread related concept? It's just a single thread thing. Is that the only place in the std where is occurs? – curiousguy May 29 '19 at 00:58
  • @JohnDvorak I have asked a [question](https://stackoverflow.com/q/56352363/963864) about the race condition created by automatic objects and the consensus seems to be that the issue doesn't exist. – curiousguy May 29 '19 at 03:43