Я искал интеллектуальные указатели, проводил модульное тестирование, как они управляют памятью, и обнаружил неожиданную проблему, которую рекомендуют делать все примеры, но это создает для меня огромную утечку памяти.
Это, кажется, происходят, когда я использую класс, у которого есть конструктор, который строится из другой копии того же класса. Я приведу пример.
Если у меня есть такой класс, как:
Class foo{
public:
//Ignore unsafe practices here
HeavyInMemory* variable;
foo(){
variable = new HeavyInMemory();
}
foo(foo* copyThis){
variable = nullptr;
if(copyThis){
variable = new HeavyInMemory(copyThis->variable);
}
}
~foo(){
delete variable;
}
}
, я обнаружу, что получу огромную утечку памяти, потому что std :: make_shared не может определить разницу между make_shared (args) и make_shared (new T)
Main(){
for(int i =0; i < 100; i++{
//Should not leak, if I follow examples of how to use make_shared
auto test = make_shared<foo>(new foo());
}
//Checking memory addresses these do not match, checking total program memory use, leaks like a
//sieve.
}
- Я что-то не так понимаю?
- Не учитывают ли примеры только то, что большинство используют примитивные типы в качестве примеров, а не классов.
- Поддерживает ли c ++ 11 формат make_shared (new T), даже если я вижу старый такие книги, как книги Скотта Мейерса 1992 года. Это просто не имеет смысла.
Кроме того, зачем вам использовать make_shared (new T) вместо make_shared (args)? Я видел пару потоков, где люди спрашивали об этом здесь, но ни один из них, по-видимому, не ответил на вопрос с примером кода.
//As they mainly say code compiler order causes the leak but in my example this would still leak:
auto originalObject = new foo();
auto expectedDestructorWhenOutofScope = make_shared<foo>(originalObject);
//I have found if I give if the object instead it doesn't leak, but this is getting into the realms of
//hacks that may sometimes work
auto originalObject = new foo();
auto expectedDestructorWhenOutofScope = make_shared<foo>(*originalObject);
РЕДАКТИРОВАТЬ: Благодаря Игорю Тандетнику, я теперь вижу, что я использую make_shared совершенно неправильно. Это следует использовать как конструктор. Еще раз спасибо Игорь, я ценю это.
//Create new
auto expectedDestructorWhenOutofScope = make_shared<foo>();
//Use object already created
std::shared_ptr<Object> p2(new foo())