2013-12-01 2 views
2

Я написал простую программу на С ++, как написано ниже:разница между PTR и & PTR

void main() 
{ 

    int *ptr; 
    ptr=new int; 
    *ptr=10; 

    cout<<ptr<<endl; 
    cout<<&ptr<<endl; 
    cout<<*ptr<<endl; 
} 

В чем разница между первыми двумя утверждениями. Оба дают адрес. Так как новый оператор резервирует память в куче, то оператор дает адрес динамически зарезервированной памяти в куче, ptr или &ptr. Теперь, если мы делаем:

delete ptr; 

Это освободит память динамически зарезервирован в куче раньше, но &ptr все еще указывает на эту ячейку памяти. Зачем ??

Я смотрел на эту ссылку для справки: https://users.cs.jmu.edu/bernstdh/web/common/lectures/slides_cpp_dynamic-memory.php

+4

'main()' должен всегда 'return'' int' в [tag: C++]! – Johnsyweb

+3

@Johnsyweb Вы помещаете обратные ссылки вокруг, чтобы указать, что это код, но в этом случае ваше утверждение неверно. Он должен возвращать 'int', но ему не требуется инструкция' return'. – hvd

+1

Я думал, что стандарт не требует возврата, но многие компиляторы сука, если у вас есть функция, возвращающая тип, который на самом деле не возвращает. Думаю, я согласен с тем, что нужно требовать возврат типа int. void - неприемлемая странность, которая должна быть вычеркнута. – RichardPlunkett

ответ

0

Во втором случае (&ptr) вы получите адрес указателя. Да, указатель - это объект, и он, в свою очередь, имеет указатель. Поэтому вы должны назначить &ptr переменной типа int **.

3
cout<<ptr<<endl; 

Отпечатано значение ptr. Это соответствует адресу, в этом случае адресу динамически распределенного int.

cout<<&ptr<<endl; 

Это печатает адрес самого указателя.

удалить ptr; ... Это освободит память, динамически зарезервированную в куче ранее, но & ptr все еще указывает на эту ячейку памяти. Зачем ??

Потому что это то, что delete делает: оно отменяет любые ptr указывает на. Вы можете повторно использовать ptr, чтобы указать на что-то еще, или установить его на nullptr, но вы должны быть явным. Имейте в виду, что многие указатели могут указывать на один и тот же динамически выделенный адрес памяти, поэтому установка одного из них на nullptr не гарантирует безопасность (спасибо @hvd за разъяснение этой части вопроса).

Примечание *: Указатели являются «специальными», потому что они содержат значения, которые являются адресами. Но у них также есть свои собственные адреса, как и любая другая переменная. Это может быть яснее, если они выраженно с типом без указателя:

int i = 42; 
std::cout << i << std::endl; // prints value of i, i.e 42. 
std::cout << &i << std::endl; // prints address of i. 
+0

Я думаю, что последнее «Почему?» о том, почему 'ptr' не сбрасывается в нулевой указатель или что-то в этом роде. Может быть любое количество переменных, указывающих на один и тот же адрес, поэтому они не могут работать достаточно надежно, чтобы быть полезными, но ОП может этого не осознавать. – hvd

+0

Ну, разница между ptr и & ptr понятна. Но проблема в том, что «delete» не выделяет то, что указывает «ptr». Например, когда я печатаю «ptr» даже после выполнения «delete ptr», он дает тот же адрес «ptr», если я явно не делаю ptr = NULL. так зачем вообще это «удалять»? почему просто мы не полагаемся на NULLING? – user3054062

+0

@ user3054062 'delete' * is * de-allocating, на что указывает' ptr'. Это его работа. Но он не делает 'ptr' a' nullptr', он оставляет его в том же месте. Доступ к этому месту будет * неопределенным поведением *. Таким образом, он 'ptr' должен использоваться после вызова' delete', вы должны либо указать его на допустимое местоположение, либо установить его в 'nullptr' (или' 0' или 'NULL' из вас, t имеет C++ 11). – juanchopanza

2

Так следующий распечатан:

cout<<ptr<<endl; // Address pointed by ptr 

cout<<&ptr<<endl;// Address of ptr 

cout<<*ptr<<endl; // Value conatined in address pointed by ptr 
0

Оператор & имеет по крайней мере три возможное значение:

  1. Когда после имени типа, например int & или int&, он поддерживает тип ссылки. int& p = q; означает, что p является ссылкой на целое число.

  2. При переходе от имени или значения переменной это означает address of.int* p = &q; означает, что p является указателем на целое число, и это значение является адресом переменной q (где q является целым числом).

  3. Бит-мудрый и.

Так что ваши

cout << &ptr << endl; 

хиты # 2 и означает "печать адрес PTR".

+0

Ну проблема «ptr» и «& ptr» понятна, но проблема, которая до сих пор не решена, заключается в том, что «delete» не де-выделяет любые точки ptr, если только мы не выполняем ptr = NULL.Например, я написал код: void main() { \t int * ptr; \t ptr = new int; \t \t cout << ptr << endl; \t cout << & ptr << endl; \t delete ptr; // \t ptr = NULL; \t cout << ptr << endl; \t cout << & ptr << endl; } и вывод, который он дает: 0x00431810 – user3054062

+0

'ptr' - это указатель, когда вы удаляете то, на что оно указывает, указатель не изменяется. '& ptr' продолжает оставаться его адресом. См. Мой ответ [здесь] (http://stackoverflow.com/questions/19672816/pointer-errors-in-the-method-of-transmissionc/19673143#19673143). В вашем контексте «удаление» эквивалентно закрытию ворот - оно не очищает бумагу и не снимает ее, но это позволяет аэропорту использовать эти ворота для другого полета. – kfsone

0

ptr является указателем на новый int, который вы выделили на кучу.

&ptr является указателем на ptr сам, который создается в стеке в вызове функции для main.

На delete ptr вы выделили на кучу нераспределенные. &ptr действителен, он указывает на переменную указателя ptr, которая существует в стеке. Вы можете использовать ptr, чтобы указать на что-то еще типа int.

Смежные вопросы