首页 > 编程语言 >C++ 指针注意事项总结

C++ 指针注意事项总结

时间:2024-08-05 09:28:33浏览次数:17  
标签:指向 使用 C++ 内存 数组 注意事项 指针

在 C++ 中,指针是一种强大的工具,允许程序员直接访问和操作内存地址。然而,由于指针直接操作内存,错误的使用可能导致程序崩溃、内存泄漏等严重问题。

以下是 C++ 指针相关的详细注意事项:

1. 指针初始化

  • 定义指针时务必初始化:未初始化的指针可能指向任意内存地址,称为“野指针”。野指针的使用可能导致程序崩溃或数据损坏。
  • 初始化方法:可以使用nullptr(C++11 及以后版本)或具体地址(如new操作符返回的地址)来初始化指针。

2. 空指针解引用

  • 避免空指针解引用:在解引用指针之前,应检查指针是否为nullptr。尝试解引用空指针将导致未定义行为,通常是程序崩溃。

3. 内存管理

  • 动态内存分配与释放:使用new操作符动态分配内存后,应使用delete(对于单个对象)或delete[](对于对象数组)来释放内存。忘记释放内存会导致内存泄漏。
  • 内存释放后置空指针:释放内存后,应将指针置为nullptr,防止成为野指针。
  • 避免重复释放:不要对同一个指针多次使用deletedelete[],这会导致未定义行为。

4. 指针运算

  • 指针算术运算:指针可以进行算术运算,如加减。但需注意,这些运算基于指针指向的数据类型的大小。例如,对指向int的指针加 1,实际上是将指针向后移动了 4 个字节(假设int占用 4 个字节)。
  • 避免越界访问:指针运算时不得越出其所指向的内存区域。

5. 指针与数组

  • 指针与数组的关系:数组名在大多数情况下被视为指向数组首元素的指针。但数组和指针在本质上并不相同,指针是一个变量,可以指向任意内存地址;而数组是一个固定大小的内存块。
  • 注意数组边界:使用指针访问数组元素时,要确保不要越界。

6. 函数中的指针参数

  • 指针作为函数参数:将指针作为函数参数传递时,函数内对指针所指向变量的修改将影响原始变量。
  • 判空操作:当指针作为函数参数时,函数体内应检查指针是否为空,以避免空指针解引用。

7. 指针类型匹配

  • 确保类型匹配:指针的类型应与它所指向的数据类型相匹配。例如,int*类型的指针应指向int类型的数据。

8. 智能指针

  • 使用智能指针:C++11 及以后版本提供了智能指针(如std::unique_ptrstd::shared_ptr)来自动管理内存,减少内存泄漏的风险。在可能的情况下,应优先考虑使用智能指针。

9. 其他注意事项

  • 避免使用 void 指针进行算术运算:void指针不指向任何具体的数据类型,对其进行算术运算是没有意义的。如果需要进行算术运算,应先将void指针转换为具体类型的指针。
  • 注意指针的生命周期:指针的生命周期应与它所指向的数据的生命周期相匹配。如果指针指向的数据在使用前已经被销毁或释放,那么解引用该指针将导致未定义行为。

总之,使用 C++ 指针时需要格外小心,遵循上述注意事项可以有效减少因指针错误使用而导致的程序错误和内存问题。

更进一步地,可参见如下详细介绍:

  1. 避免空指针解引用
  2. 注意逻辑表达式内的空指针解引用
  3. 不可解引用未初始化的指针
  4. 不可解引用已失效的指针
  5. 避免指针运算的结果溢出
  6. 未指向同一数组的指针不可相减
  7. 未指向同一数组或同一对象的指针不可比较大小
  8. 未指向数组元素的指针不应与整数加减
  9. 避免无效的空指针检查
  10. 不应重复检查指针是否为空
  11. 不应使用非零常量对指针赋值
  12. 不应使用常量 0 表示空指针
  13. 在 C++ 代码中 NULL 和 nullptr 不应混用
  14. 在 C++ 代码中用 nullptr 代替 NULL
  15. 不应使用 false 对指针赋值
  16. 不应使用 '\0' 等字符常量对指针赋值
  17. 指针不应与 false 比较大小
  18. 指针不应与 '\0' 等字符常量比较大小
  19. 指针与空指针不应比较大小
  20. 不应判断 this 指针是否为空
  21. 禁用 delete this
  22. 释放指针后应将指针赋值为空或其他有效值
  23. 函数取地址时应显式使用 & 运算符
  24. 指针与整数的加减运算应使用数组下标的方式

 

标签:指向,使用,C++,内存,数组,注意事项,指针
From: https://www.cnblogs.com/lucky-bubble/p/18342608

相关文章

  • [C++] 小游戏 决战苍穹 2.12.3版本 zty出品
       大家好,各位看到这个标题,斗破苍穹什么时候改叫决战苍穹了?其实,因为版权等一系列问题,斗破苍穹正式改名为决战苍穹,2.12.3版本主要更新内容为解决了皇冠竞技场太过影响游戏平衡,并且提高了一些装备的基础数值先赞后看,养成习惯CODE:#include<stdio.h>#include<iostream>#in......
  • c++ 容器 vector
    vector的意思就是向量,就是一个顺序表的意思,这个顺序表可以存任意的类型,因为其线性的内存特点,所以在stl里是经常被使用的存在。vectorvector既然要能储存任意的变量,那么就必须使用模板:这里的T就是变量类型,Alloc是内存池,这里先不多介绍不是vector的重点,后面我单独提出来讲。......
  • C++11 中的闭包
    什么是闭包?闭包是一种可以捕获其创建环境中的变量的函数。闭包允许函数在离开其创建环境后仍然访问和操作这些变量。Lambda表达式lambda表达式的基本语法如下:[capture](parameters)->return_type{//functionbody};capture:指定哪些外部变量可以在lambda表达式中......
  • C++11 中 声明式的编程风格
    //SetatargetPoseautoconsttarget_pose=[]{geometry_msgs::msg::Posemsg;msg.orientation.w=1.0;msg.position.x=0.28;msg.position.y=-0.2;msg.position.z=0.5;returnmsg;}();move_group_interface.setPoseTarget(target_pose);//......
  • Ros2 Moveit2 第一个C++项目
     本教程将指导您使用MoveIt编写第一个C++应用程序。警告:MoveIt中的大多数功能将无法正常工作,因为完整的MoveGroup功能需要附加参数。如需完整设置,请继续阅读MoveGroupC++接口教程。先决条件如果您还没有这样做,请确保您已经完成入门指南中的步骤。本教程假设您了......
  • 继承的特点注意事项以及类的初始化顺序和加载顺序day08
    继承的好处提高了代码的复用性多个类相同的成员可以放到同一个类中提高了代码的维护性如果功能的代码需要修改,修改一处即可让类与类之间产生了关系,是多态的前提其实这也是继承的一个弊端:类的耦合性很强......
  • 【C++从小白到大牛】栈和队列(优先级队列)
    目录引言:使用方法篇:stack:queuepriority_queue使用方法:模拟实现篇:stack:原码:queue原码:priority_queue插入和删除数据的思想:仿函数实现比较原码:引言:本文主要讲解C++STL库中stack、queue、priority_queue的使用方法和模拟实现。我们首先需要对stack、queue进......
  • 希尔排序, 插入排序, 冒泡排序, 选择排序【C++】
    希尔排序,插入排序,冒泡排序,选择排序测试代码希尔排序选择排序冒泡排序插入排序测试代码#include<iostream>usingnamespacestd;intmain(){intarr[6]={0};intlen=sizeof(arr)/sizeof(int);for(inti=0;i<len;i++){......
  • c++编写生产者消费者模型
    直接上代码啦:#include<iostream>#include<queue>#include<thread>#include<mutex>#include<condition_variable>#include<stdexcept>//定义一个同步的队列类classSyncQueue{public:SyncQueue(size_tcapacity):max_capacity(c......
  • windows C++-通过 C++/WinRT 使用 API(三)
    统一构造在C++/WinRT版本2.0及更高版本中,有一种优化的构造形式可供你使用,它被称作“统一构造”(请参见C++/WinRT2.0中的新增功能和更改)。若要使用统一构造而不是winrt::make,你需要一个激活工厂。要生成激活工厂,一种好的方式是向IDL添加构造函数。//MainPage.idl......