В C ++ отражаются ли изменения в указателях функции в вызывающей функции? - PullRequest
2 голосов
/ 14 сентября 2010

Если я передам указатель P из функции f1 в функцию f2 и изменим содержимое P в f2, будут ли эти изменения автоматически отражаться в f1?

Например, если мне нужно удалить первоеузел в связанном списке:

void f2( Node *p)
{
    Node *tmp = p;
    p = p -> next;
    delete tmp;
}

Будут ли отраженные в P изменения отражены в вызывающей функции или теперь он будет указывать на пространство памяти, которое было освобождено?

(Myинтуитивный ответ здесь - нет, изменения не отражаются. Однако хорошие источники сообщают мне, что приведенный выше код будет работать. Может, кто-нибудь найдет время дать ответ и объяснит причину его возникновения, также? Также, если приведенный выше код неисправенКак мы можем достичь этого без использования типа возврата?)

Ответы [ 2 ]

11 голосов
/ 14 сентября 2010

Если я передам указатель P из функции f1 в функцию f2 и изменим содержимое P в f2, будут ли эти изменения автоматически отражаться в f1?

Нет.Поскольку C и C ++ реализуют передачу по значению, значение указателя копируется при его передаче в функцию.Изменяется только эта локальная копия, и значение не копируется обратно при выходе из функции (это будет копирование по ссылке, поддерживаемое несколькими языками).

Если вы хотите изменить исходное значение, вам нужно передать указателю ссылку , т.е. изменить свою подпись f2 на:

void f2( Node*& p)

Однако , ваш f2 нетолько изменяет указатель p, он также меняет свое базовое значение (= значение, на которое указывает) с помощью delete. Это изменение действительно видно вызывающей стороне.

2 голосов
/ 14 сентября 2010

Это будет работать, но не так, как вы хотите.

Если вы называете это как:

Node* mynode = new Node(); /*fill data*/
f2(mynode);

-> содержимое mynode будет неопределенным.

он передаст значение указателя другой функции, и значение (p) будет локальным для функции f2. Если вы хотите изменить его, используйте этот способ:

Node* mynode = new Node(); /*fill data*/
f2(&mynode);

void f2(Node** p)
{
 Node* tmp = *p;
 *p = (*p)->next;
 delete tmp;
}
...