Передача по указателю - PullRequest
       4

Передача по указателю

13 голосов
/ 22 ноября 2011

Я запутался между этими двумя функциями:

void Swap_byPointer1(int *x, int *y){
    int *temp=new int;
    temp=x;
    x=y;
    y=temp;
}

void Swap_byPointer2(int *x, int *y){
    int *temp=new int;
    *temp=*x;
    *x=*y;
    *y=*temp;
}

Почему Swap_byPointer2 удается поменять местами x и y, а Swap_byPointer1 нет?

Ответы [ 5 ]

7 голосов
/ 22 ноября 2011

Начальная настройка функций, (общая для обеих функций) (макетные значения)

(Допущение: Значения, записанные вне полей, являются адресами. )

enter image description here

Функция swap_byPointer1,

enter image description here

Функция swapby_Pointer2,

enter image description here

Надеюсь, что это помогло получитькартина того, что происходит, ура!

7 голосов
/ 22 ноября 2011

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

Если вы хотите изменить указательуказывает на, вы должны передать указатель на указатель (то есть int**x) и изменить второй указатель.

Примерно так:

void Swap_byPointer1(int **x, int **y){
    int *temp;
    temp=*x;
    *x=*y;
    *y=*temp;
}
6 голосов
/ 22 ноября 2011

Поскольку параметры передаются по значению.В первом примере кода все, что вы делаете, это меняете локальные копии указателей.Второй пример на самом деле пишет в pointees.

Еще лучше было бы использовать передачу по ссылке и избежать выделения кучи, используя выделенную стеком temp int.

void SwapByRef(int &x, int &y)
{
    int temp=x;     
    x=y;     
    y=temp;
}
....
int x=1;
int y=2;
SwapByRef(x, y);

Как указали другие, оба ваших примера кода теряют память, потому что temp никогда не удаляется.Для простого типа int просто используйте локальную переменную int, выделенную для стека, для вашего временного секретаря.

5 голосов
/ 22 ноября 2011

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

Перезаписано без утечки памяти:

void Swap_byPointer1(int *x, int *y){
    //e.g x = 0xDEADBEEF and y = 0xCAFEBABE;
    int *temp=x;
    x=y;
    y=temp;
    //now x = 0xCAFEBABE and y = 0xDEADBEEF
}

Вторая переставляет помехи (объекты, на которые указывают указатели).

Переписано без утечки памяти:

void Swap_byPointer2(int *x, int *y){
    //e.g *x = 100 and *y = 200
    int temp =*x;
    *x=*y;
    *y=temp;
    //now *x = 200 and *y = 100
    //there are now different values at the original memory locations
}

(Указатели могут указывать на динамически размещаемые объекты, но не обязаны. Использование указателя не означает, что должен быть new -allocation. Указатели также могут указывать на объекты с автоматическим временем жизни.)

4 голосов
/ 22 ноября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...