Используйте неинициализированный указатель в качестве параметра функции - PullRequest
4 голосов
/ 05 мая 2011

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

class Body
{

};

void check(Body* b)
{
    b = new Body();
}

void checkRef(Body* &b)
{
    b = new Body();
}

int main001()
{
    Body* b;

    //check(b);// error: The variable 'b' is being used without being initialized. (in VS2010)
    checkRef(b); // OK


    return 0;
}

Какая разница, когда b передается в check и checkRef? Я получаю ошибку времени выполнения в VisualStudio2010. ошибка: переменная 'b' используется без инициализации.

РЕДАКТИРОВАТЬ: это был отладочный вывод VS2010. «ошибка» не появляется в версии

Ответы [ 4 ]

7 голосов
/ 05 мая 2011

Чтобы быть эквивалентной версии checkRef, ваша функция check должна иметь следующий вид:

void check(Body** b)
{
    *b = new Body();
}

и вызываться как

check(&b);

Если вы не пройдетеадрес, как вы делаете в check(b), затем вы передаете текущее значение указателя b, которое действительно неинициализировано.

2 голосов
/ 05 мая 2011

Body* b не устанавливает b, чтобы указать на что-либо разумное.Таким образом, он может указывать на какое-то случайное местоположение, которое может вызвать сдвиг Земли.

Передача его для проверки (по значению для указателя) не делает его инициализированным каким-либо образом

void check(Body* b)
{
    b = new Body();
}

Если вы передали его по указателю на указатель, все должно быть в порядке

  void check(Body** b)
  {
     *b = new Body();
  }

И вызов

check(&b);

Лучше сделать в C ++ с помощью эталонного примера, который вы дадите после обновлениязначение указателя, на которое ссылаются, чтобы указать на вновь выделенное тело

2 голосов
/ 05 мая 2011

In Body * &b b - псевдоним / ссылка на b в main - поэтому, когда вы назначаете его, вы изменяете b в main. В Body* b b это локальная копия b в main, вы изменяете эту локальную копию, а не b в main.

Вероятно, ваша ошибка во время выполнения связана с использованием неинициализированного b в main.

РЕДАКТИРОВАТЬ: Фактическая ошибка, которую вы получаете, представляет собой дополнительный механизм проверки типичных проблем, встроенный в ваш код вашим компилятором. Он обнаруживает, что вы передаете что-то неинициализированное по значению, что не имеет смысла, и, следовательно, генерирует эту ошибку.

Если вы отключите это поведение, приложение будет работать правильно, пока вы не попытаетесь разыменовать неинициализированный b в main

0 голосов
/ 05 мая 2011

Я не знаю, почему вы видите ошибку во время выполнения ;самое большее, я бы ожидал получить предупреждение / ошибка компиляции .Но вы, вероятно, можете это исправить, инициализировав b в NULL (но это не исправит вашу программу; см. Ниже ...)

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

...