我写了一个简单的C++程序,如下所示:
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
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.
因此打印以下内容:
cout<<ptr<<endl; // Address pointed by ptr
cout<<&ptr<<endl;// Address of ptr
cout<<*ptr<<endl; // Value conatined in address pointed by ptr
在第二种情况下(&ptr
),您将获得指针的地址。是的,指针是一个对象,它又有一个指针。因此,您可以将&ptr
分配给类型为int **
的变量。
&
运算符至少有三种可能的含义:
-
当跟随类型名称(例如
int &
或int&
)时,它会将该类型提升为引用。CCD_ 17表示p是对整数的引用。 -
在变量名称或值之前,表示
address of
。int* p = &q;
意味着p是一个指向整数的指针,它的值是变量q的地址(其中q是一个整数)。 -
有点明智。
所以你的
cout << &ptr << endl;
点击#2,意思是"打印ptr的地址"。
ptr
是指向您在堆上分配的新int
的指针。
&ptr
是指向ptr
本身的指针,它是在main的函数调用中在堆栈上创建的。
在delete ptr
上,您在堆上分配的int是未分配的。&ptr
有效,它指向堆栈上存在的ptr
指针变量。您仍然可以使用ptr
来指向其他类型的int
。