N3485 20.6.9.1 [allocator.members] / 1说:
对这些分配或取消分配特定存储单元的函数的调用应在单个总顺序中进行,并且每个这样的重新分配调用应在下一个分配(如果有)之前按此顺序进行。
这最后一项要求让我感到困惑。看起来标准是说如果一个人分配一块内存(让我们称之为块a
),然后分配另一个块(让我们称之为块b
),那么就不允许取消分配块a
,直到它取消分配块b
。
如果这确实是本段所涉及的内容,我看不出如何能够以空间有效的方式实现像vector
这样的东西;因为一个人无法分配更大的缓冲区,然后解除分配先前分配的(太小)缓冲区。
这实际上是本段的意思,还是我误读了这一部分?
答案 0 :(得分:2)
对这些分配或取消分配特定存储单元的函数的调用应在单个总订单中进行,并且每个这样的解除分配调用应在下一次分配(如果有)之前按此顺序进行。
从我看来,它只在分配和解除分配之间建立了一个先发生的关系(以防止因错误的编译器优化而产生的并发问题)。它肯定不会在a
和b
之间建立关系,其中a
和b
是不同的分配区域。
请记住,编译器遵循规范,而不是人为逻辑。规范帮助编译器程序员记住需要注意的所有细节(如果它遵循规范,那是正确的)。这就是规范包含人们认为显而易见的细节的原因。其中一个细节是释放/分配构成了一个记忆障碍。
比较
reads -> deallocation -> allocation -> writes
带
reads -> deallocation
allocation -> writes
如果没有事先发生的关系,则两个线程可以同时使用相同的存储区域(存储单元),如存储区域所观察到的那样。使用before-before关系,必须在分配线程使用它之前刷新解除分配线程的所有访问权。