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

396
27 декабря 2016, 00:33

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

Answer 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 );
Answer 2

Создается.

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

#include <iostream>
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

Рабочий пример.

READ ALSO
Вставить заданное слово после слова, кол-во букв которого четное

Вставить заданное слово после слова, кол-во букв которого четное

Как вставить заданное слово? Конкретно интересует функция InputWordЕсли я правильно понимаю, то я сначала должен увеличить память на кол-во символов...

349
Падает коннект к БД

Падает коннект к БД

Делаю проект на heroku (бесплатный аккаунт)Использую Sping + Hibernate + MySQL

323
SQL скорость выборки [требует правки]

SQL скорость выборки [требует правки]

Что будет выполняться быстрее?

321
UPDATE + сложение

UPDATE + сложение

Подскажите как сделать апдейт что бы значение в ячейке не перезатиралось, а добавлялось (если возможно без предварительной выборки сложения...

443