Страницы

Поиск по вопросам

суббота, 30 ноября 2019 г.

Передача указателей в функцию C++

#cpp #функции #указатели #ссылки #параметры


Вопрос по C++. При передаче обычной переменной в функцию создается, как я понимаю,
её копия. А что происходит, когда мы передаем указатель? Создается ли копия указателя
или нет?
    


Ответы

Ответ 1



Если у вас объявлена функция с параметром, как, например, void f( T t ); где T - это некоторый тип, и эта функция вызывается с некоторым выражением, переданным ей в качестве аргумента, как f( exp ); то инициализацию параметра можно представить следующим образом void f( /* T t */ ) { T t = exp; //... то есть параметр - это локальная переменная функции, которая инициализируется тем выражением, которое передано функции в качестве аргумента. Следовательно изменения параметра никак не сказываются на исходном аргументе, ели только тип T не является ссылочным типом. Сравните две функции void f( int *p ) { p = new int( 10 ); } void g( int * &p ) { p = new int( 10 ); } и их вызов int main() { int *p = nullptr; f( p ); if ( p == nullptr ) std::cout << "p is equal to nullptr" << std::endl; else std::cout << "p is not equal to nullptr" << std::endl; g( p ); if ( p == nullptr ) std::cout << "p is equal to nullptr" << std::endl; else std::cout << "p is not equal to nullptr" << std::endl; delete p; } В этом примере при вызове функции f имеет место утечка памяти, так как память, распределенная в функции, не освобождается. Параметр функции - локальная переменная p - при выходе из функции удаляется, и тем самым адрес выделенной динамически памяти будет утерян. У функции g параметр имеет ссылочный тип, то есть эта ссылка на переданный функции аргумент. Поэтому функция имеет дело с исходным аргументом и меняет его в своем теле, присваивая ему адрес выделенной памяти. Также можно передать указатель на указатель, если требуется изменить исходный указатель в функции. Например, void h( int **p ) { *p = new int( 10 ); } Вызов функции будет выглядеть как h( &p );

Ответ 2



Создается. Внутри функции вы можете присвоить указателю другое значение и это не повлияет на внешнюю переменную. #include void foo(int* p) { p = nullptr; std::cout << "inside: " << p << std::endl; } int main() { int v; int* p = &v; std::cout << "before: " << p << std::endl; foo(p); std::cout << "after: " << p << std::endl; } before: 0x7ffd4a1eba94 inside: 0 after: 0x7ffd4a1eba94 Рабочий пример.

Комментариев нет:

Отправить комментарий