Адрес возврата локальной переменной в C - PullRequest
12 голосов
/ 05 января 2012

Скажите, у меня есть две следующие функции:

1

int * foo()
{
  int b=8;
  int * temp=&b;
  return temp;
}

2

int * foo()
{
   int b=8;
   return &b;
}

Я не получаю никаких предупреждений для первого (например, функция возвращает адрес локальной переменной ), но я знаю, что это недопустимо, поскольку b исчезает из стека и у нас остается указатель на неопределенную память.

Так, когда мне нужно быть осторожным с возвратом адреса временного значения?

Ответы [ 5 ]

17 голосов
/ 05 января 2012

Причина, по которой вы не получаете предупреждение в первом фрагменте, заключается в том, что вы (с точки зрения компилятора) не возвращаете адрес локальной переменной.

Вы возвращаете значение int * temp. Даже если эта переменная может (и в этом примере) содержать значение, являющееся адресом локальной переменной, компилятор не пойдет вверх по стеку выполнения кода, чтобы увидеть, так ли это.

Примечание : Оба фрагмента одинаково плохи, даже если ваш компилятор не предупреждает вас о первом. Не используйте этот подход.


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

static переменные - это совершенно другой случай, который обсуждается в этой теме .

1 голос
/ 05 января 2012

Я бы сказал, что вы можете вернуть локальную переменную или, вернее, указатели на такой IF, если он был динамически выделен malloc, в этом случае память, используемая для хранения переменной, будет находиться в стеке, но в куче и не будет очищена или перезаписана.-используется после выхода из функции, как это происходит в случае автоматических локальных переменных (созданных без malloc), я прав?

0 голосов
/ 24 апреля 2012

Этот вопрос, вероятно, один из самых обсуждаемых в StackO. Ниже приведены два ответа из аналогичных тем в StackO, которые мне показались интересными и, вероятно, заставили меня отказаться от этой дурной практики отмены ссылок на локальные переменные, несмотря на то, что мои шансы получить неправильное (неопределенное поведение) очень малы.

Вот простой ответ

Мне особенно понравился этот ответ.

Вот пример, где эта плохая практика нанесла некоторый реальный аппаратный ущерб

0 голосов
/ 05 января 2012

Оба примера одинаково неверны.Я предполагаю, что ваш компилятор не видит опасности и, следовательно, не выдает предупреждение при сохранении адреса во временной переменной.

0 голосов
/ 05 января 2012

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

...