Как определить, можно ли безопасно удалить параметр функции - PullRequest
0 голосов
/ 16 января 2019

Я хочу знать, есть ли способ определить, может ли функция безопасно удалить объект, переданный в качестве параметра.

Код:

struct Test {

};

void f(Test *ptr) {
    delete ptr;   //if i delete the pointer here,
                  //i cannot use obj in main
}

int main() {
    Test *obj = new Test;

    f(new Test);
    f(obj);

    //delete obj;   //obj has already been deleted in f()
}

Есть ли способ освободить память, выделенную функцией f (новый тест), но оставить объект obj и по-прежнему использовать его в main ()?

Ответы [ 2 ]

0 голосов
/ 17 января 2019

На самом деле вы можете сделать это в C ++ 98. Нет необходимости в новом стандарте. Вы не размещаете delete внутри f. Вместо этого просто создайте объект, который вы передаете в f с помощью auto_ptr guard:

Test *obj = new Test();

f(auto_ptr<Test>(new Test()).get());
f(obj);

Автоматический указатель обеспечит освобождение объекта после завершения выполнения функции.

Ну, если честно, это * почти то же самое. Если вам явно нужно удалить указатель внутри f, а не просто охранять его, чтобы убедиться, что он освобожден, тогда вам действительно нужен умный указатель, а не просто auto_ptr, для этого вам нужно либо использовать boost или c ++ 11, либо просто написать его себя, это действительно не сложно реализовать.

Также обратите внимание, что auto_ptr устарела в новом стандарте, так что этот код не совместим с последующим.

0 голосов
/ 16 января 2019

Если вы можете перейти на C ++ 11, вы должны использовать std::shared_ptr, и ваша проблема решена. shared_ptr позаботится о количестве пользователей указателя и автоматически очистит его, когда последний пользователь удалит его. И я настоятельно рекомендую перейти на современный C ++, это решает большое количество проблем.

Вы также можете взглянуть на Boost SmartPtr - он делает то же самое и может использоваться до C ++ 11.

Вы также можете попытаться реализовать такую ​​утилиту самостоятельно, но вы должны убедиться, что реализовали ее правильно - счетчик ссылок увеличивается и уменьшается правильно в духе Правило трех


Если вам нужно использовать необработанные указатели, то в стандартном C ++ нет способа гарантировать, что указатель будет (или не будет) освобожден функцией.
Единственный способ сообщить другим программистам, что ваша функция хочет стать владельцем указателя (и удалит его), - это через документацию , либо в коде (с комментариями), либо с помощью отдельного документа (если вы создать API например).

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

...