C ++ Управление памятью путем возврата указателя на простой тип - PullRequest
1 голос
/ 17 декабря 2010

я хочу спросить о следующей ситуации

int * foo() {
    int fooint = 5;
    return &fooint;
}

int myint = *foo();

на основе http://www.functionx.com/cpp/examples/returnpointer.htm

но я хочу спросить, безопасно ли это, потому что то, что я думаю, произойдет

  • fooint инициализируется в области foo ()
  • адрес fooint возвращается и foo () заканчивается
  • все переменные в foo () уничтожаются
  • поэтому myint будет хранить значение int на уничтоженном адресе

не лучше ли будет

int * foo() {
    int * fooint = new int;
    *fooint = 5;
    return fount;
}

int * tmp = foo();
int myint = * tmp;
delete tmp;

Ответы [ 5 ]

7 голосов
/ 17 декабря 2010

Да, вы никогда не должны возвращать адреса временных переменных именно по указанным вами причинам.Второй вариант в порядке.

Однако использование динамического выделения памяти для встроенных типов будет очень дорогим.В случае встроенных типов гораздо дешевле будет просто возвращать значение:

int function()
{
    return 5;
}

, и это также будет менее подвержено ошибкам (например, нет возможности утечки памяти).

2 голосов
/ 17 декабря 2010

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

Вместо этого, пожалуйста, посмотрите на https://stackoverflow.com/questions/909323/what-are-good-online-resources-or-tutorials-to-learn-c

0 голосов
/ 17 декабря 2010

Это вызовет общую проблему, называемую висячий указатель .

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

0 голосов
/ 17 декабря 2010

Вы правы, вы не должны возвращать адреса временных переменных, а также вы не должны создавать что-то в функции, а затем возвращать это, ожидая, что вызывающая сторона очистит это (если, конечно, оно не обернуто в нечто такоеas boost::shared_ptr).

Итак, для типов, не относящихся к POD, вашему классу потребуется временный конструктор копирования (и, возможно, конструктор перемещения, если вы используете C ++ 0x для повышения производительности).).

0 голосов
/ 17 декабря 2010

Вопрос в том, почему вы хотите вернуть указатель? Обычная вещь, которую нужно сделать, это вернуть значение:

int foo() {
    int fooint = 5;
    return fooint;
}

В общем, вы должны избегать динамического выделения памяти с новым, где это возможно, и вместо этого позволить компилятору управлять всем за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...