跳到主要内容

深入指针

占用空间

size_t

size_t是unsigned long类型,size_t能保证可以存储任何类型理论上可能的对象的最大值,包括数组类型。而int类型则只能保证16位或 32位的长度,且int为有符号的类型,其能存储的范围就更小了。对于存储超过该范围的数值时,就会出现问题,而size_t则没有此问题。

size_t的大小是由生成的程序类型决定的,x86_64是8字节,x86_32是4字节。

指针

32位:4字节,64位:8字节。

野指针

定义

指向非法内存地址的指针称之为野指针,也称为悬挂指针,意思是无法正常使用的指针。

出现野指针的常见情况

使用未初始化的指针

int* p_test;
cout << *p_test << endl;

指针指向的对象已经消亡(不再存在)

int * retAddr()
{
int num = 10;
return &num;
}
int main(){
int *p = NULL;
p = retAddr();
cout << &p << endl;
cout << *p << endl;
}

这种情况可以正常运行,但输出的值并非是预期的值,而是随机的。因为在retAddr()函数执行结束后,retAddr()会执行pop出栈。此时这段内存地址会被回收。由于num也是在这段内存空间中的局部变量,所以也会被释放掉。

**Warning:**如果

--- cout << &p << endl;

或者

---  cout << &p << endl;
--- cout << *p << endl;
+++ cout << *p << endl;
+++ cout << &p << endl;

则可以正常输出num=10。原因是虽然这段内存空间被回收了,但是这里并没有对这段内存空间的修改。所以num原先所在的区域没有变动。依然能正常输出10。也就是 cout << &p << endl; 这条语句,会重用之前的栈空间,导致num的内存空间被改写。输出了不确定的值。

同样的,如果尝试修改这里p指向的这段内存空间的值,也是可以正常运行的。因为这段内存属于操作系统预留的一部分可用的栈空间,可以由任意程序改写,不属于系统的保护性地址。

指针释放后未置空

int *p = NULL;
p = new int[10];
delete p;
cout<< "p[0]:"<<p[0]<<endl;

这里由于p被释放,指针所指向的区域已经被释放,将会返回随机值。