C++指针使用与特殊指针杂谈

指针使用

  1. 指针创建时要初始化,如 int *p = NULL;
  2. 使用指针时,注意指针所指向的内存是否被分配成功,并且指向的内存是否被初始化。如
    int *p = (int *)malloc(sizeof(int));
    if(p != NULL){
    	//...
    }
    
    要注意分配后的大小,不要越界。
  3. void* 类型的指针(无类型指针),其实这种形式只是记录了一个地址。使用时要强制转换为指定类型。

当使用void*指针时,由于不知道所指向数据的类型,所以不能进行解引用和指针的算术运算,因为不知道解引用不知道获取多少字节的数据,运算时不知道跨度多大;解引用需要强制转换指针类型,如

int main(){
	void *p;
	int n = 100;
	p = &n;
	cout<<*(int*)p; // p强制转为int*类型指针后再解引用
}
  1. 两个指针最好不要指向同一块内存,一个指针的释放(free或delete)会导致另外一个指针成为悬垂指针,造成不堪设想的后果;
  2. 释放指针内存后要将该指针置空;

野指针、悬垂(悬空)指针

野指针和悬垂指针都是指向无效内存地址的指针,但它们的产生原因和性质有所不同。

悬垂指针是【已经释放的内存地址】的指针。在程序释放了一块内存之后,如果仍然存在指向该内存地址的指针,则该指针称为悬垂指针。使用悬垂指针可能会导致不可预测的行为,因为程序无法确定该内存是否已被重新分配给其他变量或对象。

野指针是指向【未知或未分配的内存地址】的指针。
通常,野指针是由于以下情况引起的:

  1. 指针未初始化,即在使用前没有将指针初始化为有效地址;
  2. 指针被释放,但在释放后仍被使用;
  3. 指针指向已经释放的内存区域;
  4. 指针越界访问了数组或缓冲区。

因此,悬垂指针是一种特定类型的野指针,它们指向已经被释放的内存地址。虽然野指针可能包含悬垂指针,但它们也可能指向未分配的内存区域,指针越界访问等其他情况,这些情况不属于悬垂指针的范畴。

空指针

空指针是一个具有特殊值(通常为0)的指针,它指向一个无效的地址。在C和C++语言中,可以使用字面值0或NULL或nullptr(在C++语言中)来表示空指针。

空指针不指向任何有效的内存地址,因此对其进行解引用或者访问指向的对象都会产生错误

const与指针

声明一个指针时,若const在*左侧,即 const * 则表示指针指向的内容是不可更改的;
反之,若 const 在*右侧,即 * const,则表示指针不能更改为指向其它内容;
另外,若 *左右各有一个const,则表示指针指向的内容不可更改,指针本身也不可更改为指向其它内容;

int n=100;
int const *p = &n;
*p = 9; // 试图通过p更改n,错误

int n1=1, n2=2;
int * const p = &n1;
p = &n2;  // 试图更改p指向其它内容,错误

int n1=1, n2=2;
int const * const p = &n1; //不能通过p修改n1,也不能更改p指向其它内容

智能指针

智能指针,本质上是对资源所有权和生命周期管理的抽象:

当资源是被独占时,使用 std::unique_ptr 对资源进行管理。
当资源会被共享时,使用 std::shared_ptr 对资源进行管理。
使用 std::weak_ptr 作为 std::shared_ptr 管理对象的观察者。
通过继承 std::enable_shared_from_this 来获取 this 的 std::shared_ptr 对象

⏩参考文章⏪

posted @ 2023-04-07 13:31  aJream  阅读(43)  评论(0)    收藏  举报