Здравствуйте, Jack128, Вы писали:
J>Здравствуйте, niXman, Вы писали:
X>>Здравствуйте, Jack128, Вы писали:
J>>>Тот же, который в vector и string используется. X>>т.е. shared_ptr сам внутрях создает объекты vector и string? оО J>Странная у тебя логика. А vector внутри себя использует new для создания vector'а ? J>Ты ж вроде занимаешся сборкой какого то компилятора? Ну загляни в сорцы тамошнего stl, увидишь зачем там дин память нужна.
Понятно что имеется ввиду несколько другой new. На сколько я понимаю/помню — весь смысл make_shared в том чтобы чтобы не было необходимости вызывать этот new.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
A>>>что? какой еще new? A>>shared_ptr помимо указателя на объект хранит еще и указатель на счетчик ссылок. Самый первый shared_ptr создает счетчик ссылок через вызов new.
EP>При использовании make_shared будет только одна аллокация.
ну, это не всегда хорошо. допустим объект большой и на него есть слабые ссылки...
Здравствуйте, night beast, Вы писали:
A>>>>что? какой еще new? A>>>shared_ptr помимо указателя на объект хранит еще и указатель на счетчик ссылок. Самый первый shared_ptr создает счетчик ссылок через вызов new. EP>>При использовании make_shared будет только одна аллокация. NB>ну, это не всегда хорошо. допустим объект большой и на него есть слабые ссылки...
Согласен, но тут либо лишняя аллокация, либо слабые ссылки держащие всю аллоцированную память. shared_ptr такой выбор предоставляет.
(можно ещё представить вариант специального взаимодействия с аллокатором, типа realloc в сторону уменьшения)
Здравствуйте, real_sba, Вы писали:
_>Понятно что имеется ввиду несколько другой new. На сколько я понимаю/помню — весь смысл make_shared в том чтобы чтобы не было необходимости вызывать этот new.
Нет, смысл его в том, чтобы обеспечить транзакционность создания объекта и умного указателя на него.
void foo(shared_ptr<X> x, Y y);
void bar()
{
foo(
shared_ptr<X>( // 3) сюда не попали, new X утёкnew X(123) // 1) ok
),
make_y() // 2) throw
);
}
void buz()
{
foo(
make_shared<X>(123), // 1) ok
// 3) удаляем временный объект
make_y() // 2) throw
);
}
А какой там менеджер памяти будет задействован — new, malloc, что-то компиляторно-специфичное, — это уже десятое дело.
Бонусом можно протащить размещение объекта и счётчика в одном блоке памяти.
Здравствуйте, Jack128, Вы писали:
J>Странная у тебя логика. А vector внутри себя использует new для создания vector'а ?
какой ответ, такой вопрос.
J>Ты ж вроде занимаешся сборкой какого то компилятора? Ну загляни в сорцы тамошнего stl, увидишь зачем там дин память нужна.
при использовании make_shared, производится только одна алокация и самого объекта, и счетчика ссылок.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Кодт, Вы писали:
_>>Понятно что имеется ввиду несколько другой new. На сколько я понимаю/помню — весь смысл make_shared в том чтобы чтобы не было необходимости вызывать этот new. К>Нет, смысл его в том, чтобы обеспечить транзакционность создания объекта и умного указателя на него. К>[...] К>А какой там менеджер памяти будет задействован — new, malloc, что-то компиляторно-специфичное, — это уже десятое дело. К>Бонусом можно протащить размещение объекта и счётчика в одном блоке памяти.
И транзакционность, и бонус производительности являются полезными свойствами make_shared.
Но тут можно поспорить, что было раньше — курица или яйцо. Например make_shared существует уже давно, а вот про make_unique, который даёт только транзакционность, без бонуса производительности, вспомнили аж после релиза ISO C++11.
6 Remarks: Implementations should perform no more than one memory allocation. [ Note: This provides
efficiency equivalent to an intrusive smart pointer. —end note ]
7 [ Note: These functions will typically allocate more memory than sizeof(T) to allow for internal
bookkeeping structures such as the reference counts. —end note ]
A>>>>что? какой еще new? A>>>shared_ptr помимо указателя на объект хранит еще и указатель на счетчик ссылок. Самый первый shared_ptr создает счетчик ссылок через вызов new. EP>>При использовании make_shared будет только одна аллокация. NB>ну, это не всегда хорошо. допустим объект большой и на него есть слабые ссылки...
Ну и если слабые ссылки не нужны — все равно тратится место на weak_count, вроде бы. Если объектов 100500 и каждый — по 10-20 байт сам по себе — то весьма заметно будет.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, niXman, Вы писали:
J>>Ты ж вроде занимаешся сборкой какого то компилятора? Ну загляни в сорцы тамошнего stl, увидишь зачем там дин память нужна. X>при использовании make_shared, производится только одна алокация и самого объекта, и счетчика ссылок.
Вроде изначальный вопрос был "как оверхед дает shared_ptr" , а не "какой оверхед дает shared_ptr при его создании через make_shared" ?
Здравствуйте, Jack128, Вы писали:
J>Вроде изначальный вопрос был "как оверхед дает shared_ptr" , а не "какой оверхед дает shared_ptr при его создании через make_shared" ?
я хз как тебе, но мне очевидно, что создавать объекты shared_ptr без использования make_shared — как-то иррационально.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, Jack128, Вы писали:
J>>Вроде изначальный вопрос был "как оверхед дает shared_ptr" , а не "какой оверхед дает shared_ptr при его создании через make_shared" ? X>я хз как тебе, но мне очевидно, что создавать объекты shared_ptr без использования make_shared — как-то иррационально.
Вовсе не очевидно. Если планируется держать weak_ptr на объекты, время жизни которых управляется с помощью shared_ptr, то возможно, более оптимальным будет отказаться от make_shared для экономии памяти.
Здравствуйте, Lazin, Вы писали:
X>>я хз как тебе, но мне очевидно, что создавать объекты shared_ptr без использования make_shared — как-то иррационально. L>Вовсе не очевидно. Если планируется держать weak_ptr на объекты, время жизни которых управляется с помощью shared_ptr, то возможно, более оптимальным будет отказаться от make_shared для экономии памяти.
Как заметил night beast, объекты ещё должны быть большими. Это означает, что:
1. размер object + ref_counting_data + alignment должен быть больше минимального кванта аллокации.
2. этот размер должен превышать некоторый практический порог, зависящий от конкретного приложения (например, кому-то намного важнее сделать меньше аллокаций, чем сэкономить несколько сотен байт).