空指针、void*指针、new及delete
2014-12-24 18:25
225 查看
如题分别总结这些和指针有关的一些知识点
1. 指向任意类型的指针void*
很多人误以为void*类型的指针就是空指针,这是不对的。void*型指针,表示定义一个指针,但不指定它指向那种类型的数据。void*类型的指针作为一种通用的指针,可以和其他任何类型的指针(函数指针除外)相互转化而不需要类型强制转换,但不能对它进行解引用及下标操作。
也就是说声明了一个void*类型的指针后,可以把任意类型的数据地址赋给该指针,但并不改变该指针的void*类型。要通过解引用访问void*指针指向的数据,就必须要先把void*指针强制转换成指向的数据类型的指针,然后再解引用访问数据。这是因为void*指针并不知道指向的数据类型的长度,所以不能直接访问数据。
第二点,如果声明了一个void*指针而没有初始化,那么该指针指向的地址是未知的,而不是NULL。
2. 空指针
空指针就是指向空地址的指针,空指针的值为0或NULL(可参照下面程序的运行结果),这个指针值对任意类型的指针都是合法的。也就是说任意类型的指针都可以初始化或置为空指针。空指针表示该指针目前处于闲置状态,没有指向任何有意义的东西。另外,空指针虽然指向“空”,但它本身作为一个数据类型的单位,是要占用内存空间的。
3. 野指针
没有初始化,并且不知道指向地址的指针就是野指针。由于野指针指向的地址未知,因此对野指针指向的地址进行写操作有可能发生未知的错误,这是非常危险的。在vs2010平台下,经过我的实验,对野指针进行访问也是非法的。以后使用指针一定要记住赋初值或在程序中赋值,否则很可能出现一些意想不到的结果。
4. new和delete
c++的动态内存分配使用new关键字,具体用法为:
typename* pt = new typename; 或者对于数组:
typename* ps = new typename [ArSize];
new关键字告诉编译器找到一块长度合适的内存块,返回首地址赋值给指针pt。该内存块保存的值由指针pt访问。
为了防止内存泄露问题出现,需要使用delete运算符来释放使用完的内存:
delete pt; 对于数组:
delete [] pt;
需要注意的是使用delete释放内存后,编译器分配给指针的内存被释放,但是指针指向的地址并不会被改变,并且这个地址仍可以被指针访问到!比较保险的做法是,释放完内存后,将指针置位空:pt = NULL,这似乎是没有区别的,但是对于一些复杂的需要大量判断的程序来说却有极大的好处,例如下述程序块:
下面一个程序验证了空指针值,被释放后的指针值是否变化,以及释放内存后指针指向的内存仍可以被访问到。
注:声明的pt、ps指针都需要初始化,否则被cout访问报错。
1. 指向任意类型的指针void*
很多人误以为void*类型的指针就是空指针,这是不对的。void*型指针,表示定义一个指针,但不指定它指向那种类型的数据。void*类型的指针作为一种通用的指针,可以和其他任何类型的指针(函数指针除外)相互转化而不需要类型强制转换,但不能对它进行解引用及下标操作。
也就是说声明了一个void*类型的指针后,可以把任意类型的数据地址赋给该指针,但并不改变该指针的void*类型。要通过解引用访问void*指针指向的数据,就必须要先把void*指针强制转换成指向的数据类型的指针,然后再解引用访问数据。这是因为void*指针并不知道指向的数据类型的长度,所以不能直接访问数据。
第二点,如果声明了一个void*指针而没有初始化,那么该指针指向的地址是未知的,而不是NULL。
2. 空指针
空指针就是指向空地址的指针,空指针的值为0或NULL(可参照下面程序的运行结果),这个指针值对任意类型的指针都是合法的。也就是说任意类型的指针都可以初始化或置为空指针。空指针表示该指针目前处于闲置状态,没有指向任何有意义的东西。另外,空指针虽然指向“空”,但它本身作为一个数据类型的单位,是要占用内存空间的。
3. 野指针
没有初始化,并且不知道指向地址的指针就是野指针。由于野指针指向的地址未知,因此对野指针指向的地址进行写操作有可能发生未知的错误,这是非常危险的。在vs2010平台下,经过我的实验,对野指针进行访问也是非法的。以后使用指针一定要记住赋初值或在程序中赋值,否则很可能出现一些意想不到的结果。
4. new和delete
c++的动态内存分配使用new关键字,具体用法为:
typename* pt = new typename; 或者对于数组:
typename* ps = new typename [ArSize];
new关键字告诉编译器找到一块长度合适的内存块,返回首地址赋值给指针pt。该内存块保存的值由指针pt访问。
为了防止内存泄露问题出现,需要使用delete运算符来释放使用完的内存:
delete pt; 对于数组:
delete [] pt;
需要注意的是使用delete释放内存后,编译器分配给指针的内存被释放,但是指针指向的地址并不会被改变,并且这个地址仍可以被指针访问到!比较保险的做法是,释放完内存后,将指针置位空:pt = NULL,这似乎是没有区别的,但是对于一些复杂的需要大量判断的程序来说却有极大的好处,例如下述程序块:
int* pt = new int [10]; ... if(pt != NULL) { delete [] pt; pt = NULL; } ...这样避免了重复释放内存块的危险。
下面一个程序验证了空指针值,被释放后的指针值是否变化,以及释放内存后指针指向的内存仍可以被访问到。
注:声明的pt、ps指针都需要初始化,否则被cout访问报错。
#include <iostream> using namespace std; int main() { void* pt = NULL; void* ps = NULL; cout << "Value of pt: " << pt << endl << "Value of pd: " << ps << endl; pt = new int; ps = new int [10]; cout << "Value of pt: " << pt << endl << "Value of pd: " << ps << endl; delete pt; delete [] ps; cout << "Value of pt: " << pt << endl << "Value of pd: " << ps << endl; *((int *)pt) = 10; cout << pt << ": " << *((int *)pt) << endl; return 0; }运行结果:
相关文章推荐
- 指针⑶,new和delete
- 指针_引用_内存管理new_delete
- C++悬挂指针: new与delete的一些理解
- C++ 学习笔记(12)动态内存、智能指针、new和delete、动态数组、allocator
- new和delete 基类指针指向继承类的对象时,delete的过程
- new、delete 与指针
- C++(4)/new delete & static & this指针 & 全局函数和成员函数
- C++的指针的坑:“new[]的指针需要delete[]”和“子类指针可以转父类指针”的两条规则成功的冲突到了一起
- C++中指针的new和delete
- C++文件头,命名空间,new和delete,内联函数,引用,函数重载,构造函数和析构函数,深拷贝和浅拷贝,explict,this指针
- 智能指针基础std::auto_ptr与new、delete的重载学习笔记
- 一级二级指针new、delete、malloc、free
- Effective STL 第7条:如果容器中包含了通过new操作创建的指针,切记在容器对象析构前将指针delete掉
- 删除(delete)空指针是安全的=>指针初始化为0或有效内存(new)
- 条款7:当使用new得指针的容器时,记得在销毁容器前delete那些指针
- c++ 浅拷贝和深拷贝 指针和引用的区别 malloc(free)和new(delete)的区别 重载重写重定义
- new、delete、指向连续空间的指针、数组、空间释放、空间申请[C++][内存管理]
- 在C++动态库中释放调用动态库程序中生成的指针new和delete 或 malloc和free
- new、delete、指向连续空间的指针、数组、空间释放、空间申请[C++][内存管理]
- 【学习】C++(1) 指针 new 和delete