首页 > 其他分享 >慎用智能指针的reset方法

慎用智能指针的reset方法

时间:2023-10-21 11:33:18浏览次数:32  
标签:reset 慎用 handler std num ptr 指针

背景

使用智能指针指向class的成员变量会导致指针Segmentation fault.

复现

直接看代码https://godbolt.org/z/Tnx45jraP

#include <iostream>
#include <memory>

struct Handler
{
    int num = 7;
};

int main()
{
    Handler handler;
    std::shared_ptr<int> ptr = nullptr;
    ptr.reset(&handler.num);
    std::cout<< *ptr << std::endl;
    return 0;
}

运行结果

ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 139
free(): invalid pointer
Program terminated with signal: SIGSEGV
7

分析

指针的值成功打印后发生错误,换成引用就没问题。
使用raw pointer int*也没问题,看来问题出在shared_ptr::reset()方法上。

template< class Y, class Deleter, class Alloc >
void reset( Y* ptr, Deleter d, Alloc alloc );

根据定义DeleterAlloc可以不传,其中Deleter会采取默认行为free()
而智能指针所管理的handler.numhandler所拥有
handler析构时也会尝试释放成员变量num最终导致double free问题。

解决

知道原因,可以想到如下解决方案:

  • 使用raw pointer代替智能指针阻止析构发生
  • 手动传入deleter方法阻止智能指针析构所指对象
    这里提供第二种代码案例https://godbolt.org/z/Kfee11qqW
#include <iostream>
#include <memory>

struct Handler
{
    int num = 7;
};

void D(void * p)
{
    std::cout<< "This deleter does nothing." << std::endl;
}

int main()
{
    Handler handler;
    std::shared_ptr<int> ptr = nullptr;
    ptr.reset(&handler.num, D);
    std::cout<< *ptr << std::endl;
    return 0;
}

参考

std::shared_ptr::reset - cppreference.com

标签:reset,慎用,handler,std,num,ptr,指针
From: https://www.cnblogs.com/azureology/p/17778693.html

相关文章

  • c语言指针
    源程序:#include<stdio.h>#include<iostream>#include<stdlib.h>usingnamespacestd;intmain(){ char*p; chara[80]; p=a; inti=0; while((*p=getchar())!='\n') { p++; i++; } a[i]='\0'; for(p=a;*p!='\0......
  • 【C语言基础】指向字符串的指针 & 字符串常量指针的关系
    问:指向字符串的指针与字符串常量指针有什么区别?答:经过实践指向字符串的指针就是字符串常量指针。字符串常量指针是常量指针的一种。常量指针的特点就是不能通过该指针来修改指向内存地址空间存储的值。 问:来看一下常见面试题char*p=“abcd”;*p=‘b’;printf("......
  • docker exec 报错 decoding init error from pipe caused \"read parent: connection
    复现方法,限制容器内pid个数dockerrun--pids-limit=1000 -dcentossleep100000dockerexec-itidbash  3.执行 foriin $(seq12000);do(sleep100&);done[root@host-226~]#dockerstatseaecCONTAINER      CPU%      ......
  • 29、Flink SQL之DESCRIBE、EXPLAIN、USE、SHOW、LOAD、UNLOAD、SET、RESET、JAR、JOB
    文章目录Flink系列文章四、SHOW语句1、java示例2、FlinkSQLcli示例3、showtables1)、语法2)、示例4、SHOWCREATETABLE5、SHOWCOLUMNS1)、语法2)、示例6、SHOWJARS7、SHOWJOBS五、LOAD语句1、语法2、Java示例3、FlinkSQLCli示例六、UNLOAD语句1、语法2、java示例3、Flink......
  • 29、Flink SQL之DESCRIBE、EXPLAIN、USE、SHOW、LOAD、UNLOAD、SET、RESET、JAR、JOB
    Flink系列文章1、Flink部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接13、Flink的tableapi与sql的基本概念、通用api介绍及入门示例14、Flink的tableapi与sql之数据类型:内置数据类型以及它们的属性15、Flink的tableapi与s......
  • 深入实践C++11智能指针
    目录概念一、std::auto_ptr二、std::unique_ptr常用函数自定义智能指针对象持有的资源的释放函数三、std::shared_ptr常用函数四、std::enable_shared_from_this五、std::weak_ptr常用函数智能指针使用注意事项智能指针的简单实现概念C/C++语言最为人所诟病的特性之一就是......
  • 第 367 场周赛(双指针,集合(upper_bound&lower_bound),前后缀分解)
    2903.找出满足差值条件的下标I2905.找出满足差值条件的下标II这两个题只有数据范围上面的差距 这个题我们大体思路是维护双指针,枚举数字,维护集合。这是灵神视频的代码classSolution:deffindIndices(self,nums:List[int],indexDifference:int,valueDiffere......
  • Acwing 800.数组元素的目标和,双指针初步
    Acwing800.数组元素的目标和给定升序的有序数组A(长度为n),B(长度为m)以及目标值x,求出满足\(A[i]+B[j]=x\)的数对\((i,j)\),题目保证仅有唯一解输入样例:456124734689输出样例:11双指针来做定义指针i,j,其中i指向A,j指向B,且i=0,指向A的首元素,j=m-1,指向B的末......
  • 【C语言】数组指针
    【C语言】数组指针顾名思义,数组指针是指向数组的指针。例如,p是一个指向含有3个int元素的一维数组的指针:int(*p)[3];//圆括号的优先级更高,让p先与*结合再与[]结合用法:#include<stdio.h>//voiddisplay1(intp[][3])//等价下行写法voiddisplay......
  • 函数指针变量
    函数指针变量函数指针变量应该是⽤来存放函数地址的,未来通过地址能够调用函数intadd(intx,inty){ returnx+y;}intmain(){ printf("%p\n",&add); printf("%p\n",add); return0;}函数是有地址的,add的地址和&add的地址一致说明函数名就是函数的地址将函数的地址......