Как увеличить количество владений указателем std :: shared

У меня есть структура с указателем в качестве члена:

struct MyStruct {
  char *ptr;
}

Я хочу инициализировать ptr в области видимости, а затем иметь возможность использовать его за пределами этой области:

{ // scope 0
    { //scope 1

        { // scope 2
            mystruct.ptr = new char[100];
        }

        // mystruct.ptr still lives here
    }

    // i dont need mystruct anymore
    delete[] mystruct.ptr;
}

Но потом мне придется удалить его позже, что чревато ошибками, и я бы предпочел избежать этого. Я решил использовать std::shared_ptr.

{ // scope 0
    { //scope 1

        { // scope 2
            auto a = std::make_shared<char>(new char[100]);
            mystruct.ptr = a.get(); // ??????? HOW TO ASSIGN
        }

        // mystruct.ptr still SHOULD live here
    }
}
  • Итак, как я мог это сделать? Как мне назначить shared_ptr для mystruct.ptr, чтобы счетчик владения стал равным 2? Я вижу, что get () не работает, потому что он просто передает указатель, но не передает права собственности, поэтому он удаляется.

  • Как видите, основная мотивация здесь - продлить жизнь, поэтому я открыт для других практик. Может, я ошибаюсь, думая об использовании здесь shared_ptr?


person Mert Mertce    schedule 20.05.2015    source источник
comment
Вы бы расширили владение на mystruct.ptr, сделав его общим указателем (или уникальным указателем, если вам специально не нужно разделять владение). Вот как работают общие указатели. Невозможно получить семантику автоматического владения из необработанного указателя.   -  person Mike Seymour    schedule 20.05.2015
comment
Я не могу изменить mystruct. Итак, с необработанным указателем я должен использовать новое-удаление?   -  person Mert Mertce    schedule 20.05.2015
comment
да. Вот почему вы не должны использовать необработанные указатели для представления владения динамическим ресурсом. Если по какой-то причине вы действительно не можете это исправить, то вам придется тщательно удалить его самостоятельно. Или договориться о том, чтобы кто-то другой владел им, и проживет столько же, сколько злой указатель.   -  person Mike Seymour    schedule 20.05.2015
comment
Почему бы не сохранить сам mystruct в интеллектуальном указателе с помощью специального средства удаления для освобождения массива символов?   -  person StoryTeller - Unslander Monica    schedule 20.05.2015


Ответы (1)


Не существует законного способа увеличить счетчик владения std :: shared_ptr, кроме присвоения его другому экземпляру std :: shared_ptr. В любом случае это не решит вашу проблему. В вашей ситуации вы должны позаботиться о правильном новом / malloc и освобождении / удалении используемой вами памяти. Если вы манипулируете share_ptr, вы должны позаботиться о том, чтобы вы также уменьшили его, иначе вы получите утечку памяти. Это такая же ситуация.

  • Если у вас есть контроль над структурой MyStruct, измените ее на std :: string или std :: shared_ptr. Если нет, придерживайтесь нового / удаляйте ИМХО. По крайней мере, читабельно и честно.
  • Если у вас есть контроль над областью 0, используйте там std :: unique_ptr. Это имеет смысл, поскольку вам не нужно заботиться об исключениях. Если вы не знаете, какой там размер, выберите новый / удалить.
person Martin Schlott    schedule 20.05.2015
comment
Нет законного способа увеличить счетчик собственности, к счастью :-) в противном случае: кто позаботится об его уменьшении? Это очень похоже на случай с std::string. - person Wolf; 20.05.2015
comment
Это будет своего рода (не существующий) std :: manual_ptr, где разработчик должен увеличивать и уменьшать счетчик. Я видел это в Objective C и MS COM. Это не работает надежно, потому что разработчик может забыть команду выпуска, так как они могут забыть освободить память. - person Martin Schlott; 20.05.2015
comment
Я думал, что когда mystruct выйдет за пределы области видимости, он автоматически перестанет владеть ptr. Но теперь я вижу, что, поскольку это необработанный указатель, мне все же пришлось его поддерживать, поэтому лучше использовать delete. - person Mert Mertce; 20.05.2015
comment
@MartinSchlott Правда? Я в шоке. BTW: в этом вопросе неясно, для чего нужны дополнительные области: может быть, чтобы предотвратить побег автоматических указателей? - person Wolf; 20.05.2015
comment
@Wolf - это хорошо, если вы хотите быть забавным, но, конечно, мы опускаем ненужные вещи, чтобы показать суть вопроса. Майк Сеймур и Мартин Шлотт хорошо поняли и ответили. - person Mert Mertce; 20.05.2015
comment
@MertMertce Будет ли std::auto_ptr вариант? Он имеет метод release. - person Wolf; 20.05.2015
comment
@MertMertce, Мартин Шлотт, хорошо, тогда кажется, что unique_ptr поможет во внутреннем объеме. - person Wolf; 20.05.2015