一、引言
*用于指针表征的含义
(1) 解引用符(单目运算符):如果预选定义了一个指针p,如int *p,那么*p就是p指向地址的值。
(2) 指针声明符(定义时):如 int *p。总是紧随类型声明符出现,是声明的一部分。
&用于指针表征的含义
(1)取地址(单目运算符):出现在表达式中。
(2)引用(定义时):这是C++在c功能上的扩展,是为了防止总是使用指针。引用指的是一个变量的别名,定义&b = a,那么b从今以后就是a的一个别名,改变b的值也就改变了a的值。指针可能指向NULL,但引用从声明开始必须赋值。引用的&总是紧随类型名出现。
二、自定义结构体
//定义
typedef struct _stArray {
int iSize=0;
double *array;
}StArray;
//初始化
this->m_stArray=new StArray{0,nullptr};
qDebug()<<"&Array=="<<&this->m_stArray->array; //&Array==0x167efd8 数组指针的地址
qDebug()<<"Array=="<<this->m_stArray->array; //Array== 0x0 数组指针指向的地址
this->m_stArray->array=new double[10];
for(int i=0;i<10;i++) this->m_stArray->array[i]=i;
qDebug()<<"&Array=="<<&this->m_stArray->array; //&Array==0x167efd8 数组指针的地址
qDebug()<<"Array=="<<this->m_stArray->array; //Array==0x1683dd0 数组指针指向的地址
qDebug()<<"*Array[0]=="<<*&this->m_stArray->array[0]; //*Array[0]== 10 数组首地址解指,及对应值
qDebug()<<"Array[0]=="<<this->m_stArray->array[0]; //Array[0]== 10 数组首地址指向的值
qDebug()<<"&Array[0]=="<<&this->m_stArray->array[0]; //&Array[0]== 0x1683dd0 数组首地址指向的值
delete[] this->m_stArray->array;
qDebug()<<"&Array=="<<&this->m_stArray->array; //&Array== 0x167efd8 数组指针的地址
qDebug()<<"Array=="<<this->m_stArray->array; //Array== 0x1683dd0 数组指针指向的地址
this->m_stArray->array=nullptr;
qDebug()<<"&Array=="<<&this->m_stArray->array; //&Array 0x167efd8 数组指针的地址
qDebug()<<"Array=="<<this->m_stArray->array; //Array== 0x0 数组指针指向的地址
三、整形指针
int a=5;
int *b=&a;
qDebug()<<"a==="<<a; //a=== 5 a的值
qDebug()<<"&a=="<<&a; //&a== 0x7df830 a的地址
qDebug()<<"b==="<<b; //b=== 0x7df830 a的地址,即b指针指向的地址
qDebug()<<"&b=="<<&b; //&b== 0x7df828 b的地址
qDebug()<<"*b==="<<*b; //*b=== 5 指向a地址的值
*b=6;
qDebug()<<"a==="<<a; //a=== 5 a的值
qDebug()<<"&a=="<<&a; //&a== 0x7df830 a的地址
qDebug()<<"b==="<<b; //b=== 0x7df830 a的地址
qDebug()<<"&b=="<<&b; //&b== 0x7df828 b的地址
qDebug()<<"*b==="<<*b; //*b=== 5 指向a地址的值---失效
a=7;
qDebug()<<"a==="<<a; //a=== 7 a的值
qDebug()<<"&a=="<<&a; //&a== 0x7df830 a的地址
qDebug()<<"b==="<<b; //b=== 0x7df830 a的地址
qDebug()<<"&b=="<<&b; //&b== 0x7df828 b的地址
qDebug()<<"*b==="<<*b; //*b=== 7 指向a地址的值
四、指针的赋值测试
int* a=new int[10];
for(int i=0;i<10;i++) a[i]=i+10;
qDebug()<<"a=="<<a; //a== 0x2e71cf0 数组指针指向的地址
qDebug()<<"&a=="<<&a; //&a== 0x7df9c8 数组指针a的地址
qDebug()<<"a[0]=="<<a[0]; //a[0]== 10
qDebug()<<"&a[0]=="<<&a[0]; //&a[0]== 0x2e71cf0
int *b=a;
qDebug()<<"b=="<<b; //b== 0x2e71cf0
qDebug()<<"&b=="<<&b; //&b== 0x7df9c0 数组指针b的地址
qDebug()<<"*b=="<<*b; //*b== 10 解指,对应的值
qDebug()<<"b[0]=="<<b[0]; //b[0]== 10
qDebug()<<"&b[0]=="<<&b[0]; //&b[0]== 0x2e71cf0
delete[] b;
qDebug()<<"a=="<<a; //a== 0x2e71cf0
qDebug()<<"&a=="<<&a; //&a== 0x7df9c8
qDebug()<<"b=="<<b; //b== 0x2e71cf0
qDebug()<<"&b=="<<&b; //&b== 0x7df9c0
qDebug()<<"b[0]=="<<b[0]; //b[0]== 10
qDebug()<<"a[0]=="<<a[0]; //a[0]== 10
qDebug()<<"&b[0]=="<<&b[0]; //&b[0]== 0x1701cf0
qDebug()<<"&a[0]=="<<&a[0]; //&a[0]== 0x1701cf0
b=nullptr;
qDebug()<<"a=="<<a; //a== 0x2e71cf0
qDebug()<<"&a=="<<&a; //&a== 0x7df9c8
qDebug()<<"b=="<<b; //b== 0x0
qDebug()<<"&b=="<<&b; //&b== 0x7df9c0
注意:通过delete[] 释放数组指针,尽管会释放其对应内存,但指针指向的地址还是存在的。
在你的代码中,当你使用 delete[] b;
释放了 a
指针所指向的内存后,a
和 b
指向的内存空间都被释放了。然而,释放内存并不会自动将指针设置为 nullptr
,所以 a
和 b
仍然保留之前的地址。这意味着,尽管内存已经被释放,但指针 a
和 b
仍然保留着之前分配的地址。
因此,在你的情况下,即使内存已经被释放,a[1]
和 b[1]
依然可能显示之前分配的值。为了避免这种情况,建议在释放内存后将指针设置为 nullptr
,以避免意外访问已经释放的内存。
int* a=new int[10];
for(int i=0;i<10;i++) a[i]=i+10;
int* &b=a;
Debug()<<"a=="<<a; //a== 0x2e31d80
qDebug()<<"&a=="<<&a; //&a== 0x7dfae8
qDebug()<<"b=="<<b; //b== 0x2e31d80
qDebug()<<"&b=="<<&b; //&b== 0x7dfae8
qDebug()<<"a[0]=="<<a[0];
b[5]=128;
qDebug()<<"a[5]=="<<a[5]; //a[5]== 128
delete[] b;
b=nullptr;
qDebug()<<"a=="<<a; //a== 0x0
qDebug()<<"&a=="<<&a; //&a== 0x7dfae8
qDebug()<<"b=="<<b; //b== 0x0
qDebug()<<"&b=="<<&b; //&b== 0x7dfae8
qDebug()<<"a[0]=="<<a[0]; //闪退,说明已经释放了
五、指向指针的指针
int* a=new int[10];
for(int i=0;i<10;i++) a[i]=i+10;
int**b=&a;
qDebug()<<"a=="<<a; //a== 0x2e82290
qDebug()<<"&a=="<<&a; //&a== 0x7dfb48
qDebug()<<"b=="<<b; //b== 0x7dfb48
qDebug()<<"&b=="<<&b; //&b== 0x7dfb40
qDebug()<<"*b=="<<*b; //*b== 0x2e82290
(*b)[5]=128;
qDebug()<<"a[5]=="<<a[5]; //a[5]== 128
delete[] *b;
*b=nullptr;
qDebug()<<"a=="<<a; //a== 0x0
qDebug()<<"*b=="<<*b; //*b== 0x0
int* a=new int[10];
int* b=new int[10];
for(int i=0;i<10;i++){a[i]=i+10;b[i]=i+20;}
int* &c=a;
for(int i=0;i<2;i++){
if(i==0)c=a;else c=b;
delete[] c;
c=nullptr;
qDebug()<<"i=="<<i<<"a=="<<a<<"b=="<<b;
}
//i== 0 a== 0x0 b== 0x2eb21a0
//i== 1 a== 0x0 b== 0x2eb21a0
int* a=new int[10];
int* b=new int[10];
for(int i=0;i<10;i++){a[i]=i+10;b[i]=i+20;}
int**c=nullptr;
for(int i=0;i<2;i++){
if(i==0){c=&a;}else{c=&b;};
delete[] *c;
*c=nullptr;
qDebug()<<"i=="<<i<<"a=="<<a<<"b=="<<b;
}
//i== 0 a== 0x0 b== 0x8c1d50
//i== 1 a== 0x0 b== 0x0
六、指针传值与传址
传指针存储地址正常释放内存
double *array1=new double[10];
qDebug()<<"array1_1==="<<array1; //array1_1=== 0x174c170
this->freeArray1(array1); //delete1=== 0x174c170
qDebug()<<"array1_2==="<<array1; //array1_2=== 0x0
void MainWindow::freeArray1(double *&ptrArray)
{
qDebug()<<"delete1==="<<ptrArray;
if(ptrArray!=nullptr){
delete[] ptrArray;
ptrArray=nullptr;
}
}
传指针指向地址-指针指向内容释放,但指针地址未释放
double *array2=new double[10];
qDebug()<<"array2_1==="<<array2; //array2_1=== 0x174c2f0
this->freeArray2(array2); //delete2=== 0x174c2f0
qDebug()<<"array2_2==="<<array2; //array2_2=== 0x174c2f0
void MainWindow::freeArray2(double *ptrArray)
{
qDebug()<<"delete2==="<<ptrArray;
double *array3=new double[10];
qDebug()<<"array3_1==="<<array3;
this->freeArray2(array3);
qDebug()<<"array3_2==="<<array3;(ptrArray!=nullptr){
delete[] ptrArray;
ptrArray=nullptr;
}
}
double *array3=new double[10];
qDebug()<<"array3_1==="<<array3; //array3_1=== 0x85c530
this->freeArray3(&array3); //delete3=== 0x85c530
qDebug()<<"array3_2==="<<array3; //array3_2=== 0x0
void MainWindow::freeArray3(double **ptrArray)
{
qDebug()<<"delete3==="<<*ptrArray;
if(*ptrArray!=nullptr){
delete[] *ptrArray;
*ptrArray=nullptr;
}
}