N3485 20.6.9.1 [allocator.members] / 1 говорит:
Вызовы этих функций, которые выделяют или освобождают конкретную единицу хранения, должны происходить в едином общем порядке, и каждый такой вызов освобождения должен происходить до следующего распределения (если оно есть) в этом порядке.
Это последнее требование смущает меня. Похоже, стандарт говорит, что если кто-то выделяет блок памяти (давайте назовем его блоком a
), а затем выделяет другой блок (назовем его блоком b
), то не разрешается освобождать блок a
пока он не освободил блок b
,
Если это действительно то, что влечет за собой этот пункт, я не понимаю, как можно реализовать что-то вроде vector
растет в космической эффективности; потому что нельзя выделить больший буфер, а затем освободить ранее выделенный (слишком маленький) буфер.
Это действительно то, что означает этот абзац, или я неправильно читаю этот раздел?
Вызовы этих функций, которые выделяют или освобождают конкретная единица хранения должен происходить в одном общем порядке, и каждый такой вызов освобождения должен происходить до следующего распределения (если оно есть) в этом порядке.
Из того, что мне кажется, он только устанавливает связь между выделением и освобождением по принципу «происходит до» (возможно, для предотвращения проблем параллелизма, возникающих из-за неправильной оптимизации компилятора). Это определенно не устанавливает отношения между a
а также b
где a
а также b
Различаются выделенные регионы.
Помните, что компиляторы следуют спецификации, а не человеческой логике. Спецификация помогает программистам компилятора запомнить все детали, о которых нужно позаботиться (если она соответствует спецификации, это правильно). Вот почему в спецификации содержатся детали, которые можно считать очевидными. Одной из деталей является то, что освобождение / распределение представляет собой барьер памяти.
сравнить
reads -> deallocation -> allocation -> writes
с
reads -> deallocation
allocation -> writes
Без отношения «до и после» два потока могут одновременно использовать одну и ту же область памяти (единицу хранения), как это наблюдается в области памяти. При наличии отношения «до и после» весь доступ из освобождающего потока должен быть сброшен до того, как выделяющий поток сможет его использовать.
Других решений пока нет …