当前位置: 首页 > news >正文

萧山区住房和城乡建设局网站进入公众号核酸检测

萧山区住房和城乡建设局网站,进入公众号核酸检测,网站开发的书籍,优秀企业网站建设公司场景 之前在如何避免出现悬垂指针[1]里说过如果避免悬垂指针的方法,即不传递和使用裸指针。 但是如果某些情况必须使用裸指针来操作,比如不得不用FILE*,HANDLE这些标准库或系统的指针时,那如何避免出现悬垂指针或空指针? 说明 …

场景

  1. 之前在如何避免出现悬垂指针[1]里说过如果避免悬垂指针的方法,即不传递和使用裸指针。 但是如果某些情况必须使用裸指针来操作,比如不得不用FILE*,HANDLE这些标准库或系统的指针时,那如何避免出现悬垂指针或空指针?

说明

  1. 裸指针在使用智能指针封装后,不再使用裸指针,那么基本能杜绝悬垂指针的情况。 可以使用宏CLOSE_UNIQUE_FILE来封装常用操作,避免写大量的冗余代码。注意,声明的宏同时把裸指针变量赋值为NULL,这避免了裸指针再次调用出现的内存安全问题。
#define CLOSE_UNIQUE_FILE(a,name) std::unique_ptr<FILE, int(*)(FILE*)> name(a,fclose);a=NULL;
#define FREE_UNIQUE_BUFFER(a,name) std::unique_ptr<char, void(*)(void*)> name(buf, free);a=NULL;
#define DELETE_SHARE_CLASS(a,name) std::shared_ptr<std::remove_pointer_t<decltype(a)>> name(a, [](decltype(a) str) { delete str; });a=NULL;void TestMalloc()
{// 2. 有些`C`接口返回的`char*`类型;是通过`malloc`创建的.auto buf = (char*)malloc(32);FREE_UNIQUE_BUFFER(buf, spBuf);
}void TestWin32HANDLE()
{// 3. `Win32`对象WIN32_FIND_DATA findFileData;HANDLE hFind = FindFirstFile(L".\\*.*", &findFileData);if (hFind == INVALID_HANDLE_VALUE)return;std::shared_ptr<void> spFind(hFind, ::FindClose);
}void TestFILE()
{// 1. 使用`fopen_s`// -- 使用`unique_ptr`FILE* file = NULL;auto err = fopen_s(&file,"1.txt", "rb");if (err != 0)return;CLOSE_UNIQUE_FILE(file, spFile);
}
  1. 把变量赋值为NULL,空指针调用非虚函数,而虚函数里不会访问它的成员变量时,这个行为是未定义,可能会崩溃,也可能不会。经验来看,很少会出现崩溃的情况。那么如何让空指针调用非虚函数一定会崩溃呢?让空指针解引用,这种方式一定会在运行时崩溃。一般有两种方式实现。

    • public非虚函数的最前面增加判断this == nullptr,如果为true,那么抛出异常。可以声明的宏CHECK_NULL。这种方式就是麻烦,要程序员自己记住。C++的 避免内存安全问题的方式就是要程序员遵守规则。
    
    #define CHECK_NULL() if(this == nullptr) throw std::runtime_error("Null pointer dereference!");class A
    {public:A(const std::string& name) :name_(name) {}~A() {std::cout << "~A" << std::endl;}virtual void sayNo() {std::cout << "No " << std::endl;}void sayBye() {// -- 不要使用断言`assert`,因为在`Release`模式可能会被优化掉。CHECK_NULL();std::cout << "Bye " << std::endl;}private:std::string name_;
    };
    
    • 把方法声明为virtual,因为访问vtable虚函数表需要this解引用再调用方法。只要空指针this解引用就一定崩溃。如上边的sayNo方法。
  2. 避免悬垂指针和空指针的有效方法就是避免操作裸指针,创建后就不用了。

例子

  1. 这个例子再次细化了避免悬垂指针的方法。
#include <iostream>
#include <memory>
#include <assert.h>
#include <stdio.h>
#include <Windows.h>// -- 不允许直接访问指针.
#define CLOSE_UNIQUE_FILE(a,name) std::unique_ptr<FILE, int(*)(FILE*)> name(a,fclose);a=NULL;
#define FREE_UNIQUE_BUFFER(a,name) std::unique_ptr<char, void(*)(void*)> name(buf, free);a=NULL;
#define DELETE_SHARE_CLASS(a,name) std::shared_ptr<std::remove_pointer_t<decltype(a)>> name(a, [](decltype(a) str) { delete str; });a=NULL;#define CHECK_NULL() if(this == nullptr) throw std::runtime_error("Null pointer dereference!");class A
{public:A(const std::string& name) :name_(name) {}~A() {std::cout << "~A" << std::endl;}virtual void sayNo() {std::cout << "No " << std::endl;}void say() {std::cout << "hello " <<  name_.c_str() << "!" << std::endl;}void sayYes(){std::cout << "Yes " << std::endl;}void sayBye() {// -- 不要使用断言`assert`,因为在`Release`模式可能会被优化掉。CHECK_NULL();std::cout << "Bye " << std::endl;}private:std::string name_;
};void TestMalloc()
{// 2. 有些`C`接口返回的`char*`类型;是通过`malloc`创建的.auto buf = (char*)malloc(32);FREE_UNIQUE_BUFFER(buf, spBuf);
}void TestWin32HANDLE()
{// 3. `Win32`对象WIN32_FIND_DATA findFileData;HANDLE hFind = FindFirstFile(L".\\*.*", &findFileData);if (hFind == INVALID_HANDLE_VALUE)return;std::shared_ptr<void> spFind(hFind, ::FindClose);
}void TestFILE()
{// 1. 使用`fopen_s`// -- 使用`unique_ptr`FILE* file = NULL;auto err = fopen_s(&file,"1.txt", "rb");if (err != 0)return;CLOSE_UNIQUE_FILE(file, spFile);
}void TestVoid()
{auto a = new A("infoworld");DELETE_SHARE_CLASS(a, spA);spA->say();// `NULL`指针调用非虚函数可能不崩溃,未定义行为。// -- 可能会崩溃,可能不会。a->sayYes();// -- 但是调用成员变量就会崩溃,因为要对`this`解引用访问成员变量,即对`NULL`解引用必然崩溃。//a->say();// -- 方法1:调用虚函数需要查找虚函数表,解引用`this`也必然崩溃。//a->sayNo();// -- 方法2:使用宏来判断`this`是否为`NULL`//    如果不捕抓,就会在运行时崩溃。try {a->sayBye();}catch (const std::exception& e) {std::cout << e.what() << std::endl;}}int main()
{std::cout << "Hello World!\n";TestFILE();TestMalloc();TestWin32HANDLE();TestVoid();
}

输出

Hello World!
hello infoworld!
Yes
Null pointer dereference!
~A

参考

  1. 如何避免出现悬垂指针

  2. decltype

http://www.dtcms.com/a/475057.html

相关文章:

  • 记录oracle19c安装完成后,使用navcat连接数据库一直报错ORA-00922: 选项缺失或无效
  • 网站不被收录自建网站推广的最新发展
  • 泰安微信网站建设asp.net 当前网站
  • LINUX复习资料(二)
  • 基于视觉与IMU融合的地下停车场自动导航系统原理与实现
  • 国外域名购买网站品牌策划方案设计
  • 外设模块学习(5)——DS18B20温度传感器(STM32)
  • 网站增加点击率 怎样做app制作哪里正规
  • 自己做的网站慢是什么原因哪些网站微信支付平台
  • 编程语言比较从Java到C++,探索主流开发工具的特性与应用场景
  • 自定义网站模板科技公司网页设计欣赏
  • 【完整源码+数据集+部署教程】管道与支架检测系统源码和数据集:改进yolo11-RepNCSPELAN
  • 长沙便宜网站建设手机设计软件下载大全
  • Unity网络开发--自定义协议生成工具
  • 做宣传类网站需要什么资质浙江省建设执业注册中心网站
  • 怎么做视频解析的网站网站数据分析
  • 营销网站建站长沙营销型网站设计
  • 多输入,多输出来学英语
  • 矩阵的除法
  • 网站建设与优化推广方案内容WordPress安装插件要FTP
  • 合肥网站推广 公司哪家好手机论坛网站模板
  • 什么网站做唱歌主播网站建设 说明
  • 建设户外腰包网站旅游网站开发价格
  • CRYSTALS-Kyber在TLS 1.3中的实现挑战
  • 伴随矩阵的定义
  • PagedAttention详解
  • 网站搭建软件微信公众号对接网站如何做
  • 北京哪个公司做网站宁波网站设计制作
  • c2c模式的典型网站宜宾网站建设
  • 假网站网站怎么做网站关于我们什么意思