байт неинициализированной памяти при вызове

я заменю всеoperator new подписи, которые я могу, по крайней мере в тестируемых реализациях, я вижу, что стандартные контейнеры обращаются к моим замененным версиям для выделения памяти.

Это гарантировано стандартом? То есть было бы незаконно для реализации использовать оптимизированную версию, которая не вызывала мои функции замены для памяти, лежащей в основе стандартных контейнеров?

 Peter Cordes19 окт. 2017 г., 07:46
Контекст этого вопроса: могstd::vector<T> (с распределителем по умолчанию) использоватьrealloc а такжеcalloc вместо более слабогоnew API.new не может получить выгоду от получения уже обнуленных страниц из ОС (избегаяmemset(0)) или расширение отображения, если это возможно, когда ничто другое не использует это виртуальное адресное пространство.
 MSalters19 окт. 2017 г., 10:16
Обратите внимание, что некоторые контейнеры (std::string в частности) может не хранить все элементы в выделенной памяти, но может хранить некоторые элементы в самом объекте контейнера. Google "Small String Optimization" для деталей.
 bartoli19 окт. 2017 г., 14:40
Если эта гарантия важна для вашей программы, что может привести к потере производительности, у вас также есть выбор - распределить их самостоятельно так, как вы хотите, и хранить только указатели в контейнере.
 StaceyGirl17 нояб. 2017 г., 12:57
@PeterCordes Я не думаю, что это возможно. Даже если глобальныйoperator new заменяется,std::vector<T> все еще полагается на интерфейс распределителя, чтобы делать распределения, и этот интерфейс не предоставляет способ выделить инициализированный по умолчанию массив или способ перераспределить данные - эти операции выполняются самим вектором. В теорииstd::vector<T> Возможно, он может быть специализирован для стандартных типов макетов, использующих стандартный распределитель, чтобы использовать более эффективную технику, но я не думаю, что кто-то делает это.
 Basile Starynkevitch19 окт. 2017 г., 07:17
Я считаю, что да, по крайней мере, на практике. Однако я недостаточно хорошо знаю стандарт C ++, чтобы цитировать его

Ответы на вопрос(2)

таких какstd::vector<T> являетсяstd::allocator<T>, Этот шаблон класса описан в разделе [default.allocator] стандарта. Согласно [allocator.members] / 6 в C ++ 14:

хранение получается по телефону::operator new(std::size_t)

Таким образом, глобальный оператор new - это тот, который вам нужно заменить. Если вы перегруженыoperator new специально дляTперегруз будетне использоваться распределителем по умолчанию.

 Peter Cordes19 окт. 2017 г., 08:26
Так что это было бы незаконно дляstd::vector реализация на самом деле использоватьcalloc под капотом, даже на платформе, гдеnew а такжеmalloc совместимы, если библиотека + компилятор не может обнаружить / доказать, что::operator new(std::size_t) не было отменено? (В этом случае правило «как будто» должно позволять это с оптимизацией всей программы)."не указано, когда и какnew называется "языка достаточно, чтобы оптимизировать или объединить некоторые распределения, но не позволит обойтиnew в целом, верно?
 Brian19 окт. 2017 г., 08:55
@PeterCordes Я уверен, что это правильная интерпретация, да.

Пока вы не используете пользовательский распределитель для создания экземпляра контейнера, я считаю, что это правда.

Изhttp://en.cppreference.com/w/cpp/memory/allocator

std::allocator Шаблон класса - это Распределитель по умолчанию, используемый всеми стандартными контейнерами библиотеки, если не указан пользовательский распределитель.

а также

Изhttp://en.cppreference.com/w/cpp/memory/allocator/allocate:

Выделяетn * sizeof(T) байт неинициализированной памяти при вызове::operator new(std::size_t)

Ваш ответ на вопрос