在C++的union中使用std::string(非POD对象)的陷阱

struct和union的对比

union最开始是C语言中的关键字,在嵌入式中比较常见,由于嵌入式内存比较稀缺,所以常用union用来节约空间,在其他需要节省内存的地方也可以用到这个关键字,写一个简单程序来说明union的用途

struct:

写一个最简单的struct结构体:

struct S
{int i;double d;char c;
};
int main()
{S s;cout<<sizeof s<<endl;
}

最后得到结果为24

int占4位,double占8位,c占1位

由于内存对齐的原因,最后用了3*8 = 24字节

 其在内存布局如下:

union:

将这个结构体改为union类型:

union U
{int i;double d;char c;
};
int main()
{U u;cout<<sizeof u<<endl;
}

最后输出结果为8

union的三个变量公用一段内存,所以同时只能存储一个变量

其内存布局如下:

读取值得本质是取到add,按照不同方式进行读取,类似于下面的代码

u.i =(int)(*add);
u.d = (double)(*add);
u.c = (c)(*add);

union中的string

将编译条件改为-std=c++03:

union U
{int i;double d;string s;
};

会发现不支持使用string 

因为string不属于POD对象,有构造函数,为了和C语言兼容,所以在旧版中禁止了在union中使用非POD对象

不过在后面的C++版本中取消了这个限制

将编译条件改为-std=c++11,编译通过,所以在后面可以在union中使用带构造方法的对象了;

执行如下例子:

#include <iostream>
#include <string>using namespace std;union U
{U(int i){_i = i;}U(string s){_s = s;}string _s;int _i;
};int main()
{U *u =new U("hello");cout<<u->_s<<endl;
}

输出正常结果:

然而这里有一个问题:

这个对象是无法析构的!!!

union中手动添加析构函数及使用析构函数中的陷阱

加上析构函数:

int main()
{U *u =new U("hello");cout<<u->_s<<endl;delete u;
}

直接报错:

这时候,加上析构函数释放内存就可以了:

	~U(){_s.~string();}

这样就可以在union中使用string等非POD对象了

但是会出现一个比较大的陷阱,当这个union中存的不为string的时候

int main()
{U *u =new U(12);delete u;
}

这时候调用delete u时,~U()的~string()就会出错(对着一个int类型使用string的析构):

这就需要另外处理了,比如判空

	~U(){if(!_s.empty(){_s.~string();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/252992.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试150 位1的个数 位运算

Problem: 191. 位1的个数 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 参考 复杂度 Code public class Solution {// you need to treat n as an unsigned valuepublic int hammingWeight(int n){int res 0;while (n ! 0){res 1;n & n - 1;// 把最后…

Python程序员面试题精选(1)

本文精心挑选了10道Python程序员面试题&#xff0c;覆盖了Python的多个核心领域&#xff0c;包括装饰器、lambda函数、列表推导式、生成器、全局解释器锁(GIL)、单例模式以及上下文管理器等。每道题都附有简洁的代码示例&#xff0c;帮助读者更好地理解和应用相关知识点。 题目…

【漏洞复现】电信网关配置管理系统SQL注入漏洞

Nx01 产品简介 电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员实现对网关设备的远程监控、配置、升级和故障排除等功能&#xff0c;从而确保网络的正常运行和高效性能。 Nx02 漏洞描述 电信网关配置管理系统存在SQL注入漏洞,攻…

第3节、电机定速转动【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍用定时器定时的方式&#xff0c;精准控制脉冲时间&#xff0c;从而控制步进电机速度。 一、计算过程 电机每一步的角速度等于走这一步所花费的时间&#xff0c;走一步角度等于步距角&#xff…

记录 | linux下切换python版本

查看系统中存在的 python 版本 ls /usr/bin/python* 查看系统默认的 python 版本 python --version

探索Web API SpeechSynthesis:给你的网页增添声音

Web API SpeechSynthesis是一项强大的浏览器功能&#xff0c;它允许开发者将文本转换为语音&#xff0c;并通过浏览器播放出来。本文将深入探讨SpeechSynthesis的控制接口&#xff0c;包括其功能、用法和一个完整的JavaScript示例。 参考资料&#xff1a;SpeechSynthesis - Web…

网络基础(三)

网络层与数据链路层 1.网络层2.IP2.1 基本概念2.2 协议头格式2.3 网段划分2.4 特殊的IP地址2.5IP地址的数量限制2.6 私有IP地址和公网IP地址2.7 路由 3.数据链路层4.以太网&#xff08;MAC帧协议&#xff09;4.1 认识以太网4.2 以太网帧格式4.3 认识MAC地址4.4 对比理解MAC地址…

[SWPUCTF 2021 新生赛]ez_unserialize

根据下面的user_agent和Disallow可以判断这个是在robots.txt 我们看的出来这是一个反序列化需要我们adminadmin passwdctf construct 构造方法&#xff0c;当一个对象被创建时调用此方法&#xff0c;不过unserialize()时却不会被调用 destruct 析构方法&#xff0c;PHP将在对象…

使用 VTK 中的单元定位器来查找最近的点

开发环境&#xff1a; Windows 11 家庭中文版Microsoft Visual Studio Community 2019VTK-9.3.0.rc0vtk-example demo解决问题&#xff1a;使用 VTK 中的单元定位器来查找最近的点 关键点&#xff1a; 创建了一个球体数据源&#xff0c;并使用它构建了一个单元定位器&#x…

哪些是暴利的行为?合法的暴利行为?哪些行为为极善 相对于极恶?

合法的暴利行为 在讨论暴利的合法行为时&#xff0c;重要的是要区分“暴利”一词通常带有负面含义&#xff0c;指的是通过不正当手段或在不具备公平竞争条件下获得的过高利润。然而&#xff0c;有些行业或商业模式在法律范围内运作&#xff0c;可能因为专利保护、市场垄断、技…

计算机网络——网络

计算机网络——网络 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU)前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c; [跳转到网站](https://www.captainbed.cn/qianqiu) 无线网络和移动网…

[C/C++] -- JSON for Modern C++

JSON for Modern C&#xff08;nlohmann/json&#xff09;是一个流行的 C JSON 库&#xff0c;由德国开发者nlohmann编写。这个库提供了简洁而灵活的 API&#xff0c;使得在C中解析和生成JSON数据变得非常方便。 1.JSON简介 JSON&#xff08;JavaScript Object Notation&…

text-generation-webui搭建大模型运行环境与踩坑记录

text-generation-webui搭建大模型运行环境 text-generation-webui环境初始化准备模型启动项目Bug说明降低版本启动项目 text-generation-webui text-generation-webui是一个基于Gradio的LLM Web UI开源项目&#xff0c;可以利用其快速搭建部署各种大模型环境。 环境初始化 下载…

在容器中使用buildah构建镜像

简介 buildah是一个构建OCI标准镜像的工具&#xff0c;可以用来替代docker build 在常见的linux发行版中可直接通过包管理工具安装使用 # centos yum install buildah# ubuntu/debian apt install buildah# alpine apk add buildah其他发行版安装方法详见 github&#xff0c…

OpenCV-31 获得形态学卷积核

OpenCV提供了获取卷积核的API&#xff0c;不需要我们手动创建卷积核。 通过下面API---getStructuringElement(shape&#xff0c;ksize&#xff0c;[, anchor]) shape是指卷积核的型状&#xff0c;注意不是指长宽&#xff0c;是指卷积核中1形成的形状。MORPH_RECT 卷积核中的1…

【数据分享】1929-2023年全球站点的逐日降水量数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;说到常用的降水数据&#xff0c;最详细的降水数据是具体到气象监测站点的降水数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全…

数据结构——C/栈和队列

&#x1f308;个人主页&#xff1a;慢了半拍 &#x1f525; 创作专栏&#xff1a;《史上最强算法分析》 | 《无味生》 |《史上最强C语言讲解》 | 《史上最强C练习解析》 &#x1f3c6;我的格言&#xff1a;一切只是时间问题。 ​ 1.栈 1.1栈的概念及结构 栈&#xff1a;一种特…

【Linux】线程Pthread的概念 | NPTL线程库函数

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;Linux系列专栏&#xff1a;Linux基础 &#x1f525; 给大家…

麒麟信安连续两年获评信创工委会“卓越贡献成员单位”荣誉称号

近日&#xff0c;中国电子工业标准化技术协会信息技术应用创新工作委员会&#xff08;以下简称信创工委会&#xff09;向麒麟信安授予2023年度“卓越贡献成员单位”荣誉称号并发来感谢信。 信中对2023 年麒麟信安在信创工委会发展中作出的重要贡献表示衷心感谢&#xff0c;并表…

Camunda流程引擎数据库架构

&#x1f496;专栏简介 ✔️本专栏将从Camunda(卡蒙达) 7中的关键概念到实现中国式工作流相关功能。 ✔️文章中只包含演示核心代码及测试数据&#xff0c;完整代码可查看作者的开源项目snail-camunda ✔️请给snail-camunda 点颗星吧&#x1f618; &#x1f496;数据库架构…