qt初入门0:结构体中QString用memset导致崩溃分析及QLatin1String简单查看源码

初识Qt,进行开发时遇到一个崩溃问题 简单整理

1:问题描述如下,结构体中QString成员,然后对结构体调用了memset导致问题:

在这里插入图片描述

2:问题分析,加断点调试的方式可以明确分析到行数

可以明确看出,初始化时成员变量的值为空的字符串,然后执行memset后,该成员地址无法访问。
在这里插入图片描述

3:找源码进行分析一下

3.1.这里首先测试一下string等其他成员操作,没有出现问题。

3.2 分析QString的源码,了解原因(qtbase源码分析)。

简化后源码如下

const QArrayData QArrayData::shared_null[2] = {{ -1, 0, 0, 0, sizeof(QArrayData) }, }
inline QString::QString() noexcept : d(Data::sharedNull()) {}
inline QString::~QString() { if (!d->ref.deref()) Data::deallocate(d); }class Q_CORE_EXPORT QString
{
public:typedef QStringData Data; //基类是 QArrayDatainline QString() noexcept;
private:Data *d; //基类是 QArrayData 控制引用计数
public:typedef Data * DataPtr;inline DataPtr &data_ptr() { return d; }
};QString::QString(const QChar *unicode, int size)
{if (!unicode) {d = Data::sharedNull();} else {if (size < 0) {size = 0;while (!unicode[size].isNull())++size;}if (!size) {d = Data::allocate(0);} else {d = Data::allocate(size + 1);Q_CHECK_PTR(d);d->size = size;memcpy(d->data(), unicode, size * sizeof(QChar));d->data()[size] = '\0';}}
}

第一个分析点(构造函数):
在这里插入图片描述

第二个分析点,真正控制QString的数据体,只能指针+数据域

实际真正的底层是QArrayData

struct Q_CORE_EXPORT QArrayData
{QtPrivate::RefCount ref; //基类实现原子变量的递增递减int size;uint alloc : 31;uint capacityReserved : 1;qptrdiff offset; // in bytes from beginning of headervoid *data() {Q_ASSERT(size == 0  || offset < 0 || size_t(offset) >= sizeof(QArrayData));return reinterpret_cast<char *>(this) + offset;}static const QArrayData shared_null[2];static QArrayData *sharedNull() noexcept { return const_cast<QArrayData*>(shared_null); }
};//真正的申请内存
QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,size_t capacity, AllocationOptions options) noexcept
{Q_ASSERT(alignment >= Q_ALIGNOF(QArrayData)            && !(alignment & (alignment - 1)));if (!(options & RawData) && !capacity) {return const_cast<QArrayData *>(&qt_array_empty);}size_t headerSize = sizeof(QArrayData);if (!(options & RawData))headerSize += (alignment - Q_ALIGNOF(QArrayData));if (headerSize > size_t(MaxAllocSize))return nullptr;size_t allocSize = calculateBlockSize(capacity, objectSize, headerSize, options);QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));if (header) {quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1)& ~(alignment - 1);header->ref.atomic.storeRelaxed(1);header->size = 0;header->alloc = capacity;header->capacityReserved = bool(options & CapacityReserved);header->offset = data - quintptr(header);}return header;
}//真正的释放内存 根据引用计数控制
void QArrayData::deallocate(QArrayData *data, size_t objectSize, size_t alignment) noexcept
{// Alignment is a power of twoQ_ASSERT(alignment >= Q_ALIGNOF(QArrayData)  && !(alignment & (alignment - 1)));Q_UNUSED(objectSize) Q_UNUSED(alignment)Q_ASSERT_X(data == 0 || !data->ref.isStatic(), "QArrayData::deallocate","Static data cannot be deleted");::free(data);
}

4:为什么string成员没有问题呢(分析QLatin1String)

这里在看QString源码时看到了QLatin1String类 区分QString进行了简单查看。

首先:QLatin1String作为结构体成员,也没有问题。
在这里插入图片描述

4.1 简单查看QLatin1String的源码

class QLatin1String
{
public:Q_DECL_CONSTEXPR inline QLatin1String() noexcept : m_size(0), m_data(nullptr) {}Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s) noexcept : m_size(s ? int(strlen(s)) : 0), m_data(s) {}Q_DECL_CONSTEXPR explicit QLatin1String(const char *f, const char *l): QLatin1String(f, int(l - f)) {}Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s, int sz) noexcept : m_size(sz), m_data(s) {}inline explicit QLatin1String(const QByteArray &s) noexcept : m_size(int(qstrnlen(s.constData(), s.size()))), m_data(s.constData()) {}//。。。其他都是基本的函数接口Q_DECL_CONSTEXPR const char *latin1() const noexcept { return m_data; }Q_DECL_CONSTEXPR int size() const noexcept { return m_size; }Q_DECL_CONSTEXPR const char *data() const noexcept { return m_data; }Q_DECL_CONSTEXPR bool isNull() const noexcept { return !data(); }Q_DECL_CONSTEXPR bool isEmpty() const noexcept { return !size(); }private:int m_size;const char *m_data;
};

4.2 简单分析 QLatin1String 就是对char*的简单封装

在这里插入图片描述

4.2 细节,没看到有operator= 使用赋值构造也没有问题

这是因为用了浅拷贝,内部没涉及内存的重新申请 所以也没问题。

然后因为demo中x1重新赋值,浅拷贝导致x1中data指向的const char*指向发生变化。

总结:QLatin1String只是对char*的简单封装,不涉及内存的申请,实际还是需要我们控制。

遗留:过程中看到QString中相关的编码相关函数,这块也是一个细节,待整理

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

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

相关文章

Windows下问题定位

1、内存相关知识点&#xff1b; 1&#xff09;windows下32位进程&#xff0c;用户态为2G内存&#xff0c;内核态也为2G内存&#xff1b;却别于linux操作系统&#xff1b; 备注&#xff1a;可以通过命令行与管理员权限&#xff0c;启动3G的用户态空间&#xff0c;但是部…

git权限问题解决方法Access denied fatal: Authentication failed

文章目录 遇到Access denied 的权限问题解决方法1、git的密码修改过&#xff0c;但是本地没更新。2、确定问题&#xff0c;然后增加配置① 查询用户信息②如果名称和email不对&#xff0c;设置名称&#xff1a;③ 检查ssh-add是否链接正常④ 设置不要每次都输入用户名密码 3、配…

【校招VIP】CSS校招考点之选择器优先级

考点介绍&#xff1a; 选择器是CSS的基础&#xff0c;也是校招中的高频考点&#xff0c;特别是复合选择器的执行优先级&#xff0c;同时也是实战中样式不生效的跟踪依据。 因为选择器的种类较多&#xff0c;很难直接记忆&#xff0c;可以考虑选择一个相对值&#xff0c;比如id类…

人大进仓数据库ksql命令基础

测试环境信息: 系统为银河麒麟V10 数据库为Kingbase ES V8 数据库安装目录为/opt/Kingbase/ES/V8 ksql命令位于/opt/Kingbase/ES/V8/Server/bin下 使用--help获取帮助 续上图 1.查看数据库列表 ./ksql -U system -l 2.查看数据库版本 ./ksql -V 3.连接指定的数据库tes…

【GAMES202】Real-Time Shadows2—实时阴影2

一、PCSS回顾 上一篇我们说了如何用PCSS是实现软阴影&#xff0c;这个过程是没有任何问题的&#xff0c;但是有一个速度的问题&#xff0c;因为PCSS涉及到非常多次对纹理特定某一块区域遍历的操作&#xff08;工业界一般都是用在该区域采样的方式&#xff0c;会因此产生噪声&am…

Zookeeper集群单节点启动成功但未同步其他节点数据

首先排查节点启动是否正常&#xff1a; 在zookeeper的bin目录下执行&#xff1a;sh zkServer.sh status 判断当前节点数据leader 还是follower 节点都启动正常&#xff0c;但某一个zookeeper集群节点&#xff08;下面简称“异常节点”&#xff09;不同步其他节点数据&#xf…

SQL-每日一题【1321. 餐馆营业额变化增长】

题目 表: Customer 你是餐馆的老板&#xff0c;现在你想分析一下可能的营业额变化增长&#xff08;每天至少有一位顾客&#xff09;。 计算以 7 天&#xff08;某日期 该日期前的 6 天&#xff09;为一个时间段的顾客消费平均值。average_amount 要 保留两位小数。 结果按 …

最新两年工作经验总结

最新两年工作经验总结 前言URP的使用1&#xff1a;如何开启URP1、老项目升级为URP2、创建新项目时选择URP创建 2&#xff1a;URP阴影的设置 PolyBrush的使用&#xff08;地图编辑插件&#xff09;制作山峰or低谷边缘柔化雨刷上色制造场景中的物体贴图地形创建容易踩坑的点ProBu…

java 工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发 em

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显…

【C++习题集】-- 堆

&#xff08;用于复习&#xff09; 目录 树概念及结构 名词概念 二叉树概念及结构 特殊的二叉树 满二叉树 完全二叉树 运算性质 二叉树存储结构 顺序存储 链式存储 堆 - 顺序存储 堆的性质 堆的实现 堆的应用 堆排序 直接建堆法 树概念及结构 概念&#xff1a…

编写Dockerfile制作自己的镜像并推送到私有仓库

说明&#xff1a;我将用到的私有仓库是Harbor&#xff0c;安装教程参考我的这一篇文章&#xff1a; 安装搭建私有仓库Harbor_Word_Smith_的博客-CSDN博客 一、案例1 1、要求 编写Dockerfile制作Web应用系统nginx镜像&#xff0c;生成镜像nginx:v1.1&#xff0c;并推送其到私…

【高级IO】- 五种 IO 模型 | 多路转接 - select

目录 IO的基本概念 什么是高效的IO&#xff1f; 五种IO模型 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO 同步通信VS异步通信&#xff08;synchronous communication / asynchronous communication&#xff09; 同步通信VS同步与互斥 阻塞VS非阻塞 其他高级IO …

JavaScript高级

1、JavaScript面向对象 1.1、面向对象介绍 ​ 在 Java 中我们学习过面向对象&#xff0c;核心思想是万物皆对象。在 JavaScript 中同样也有面向对象。思想类似。 1.2、类的定义和使用 结构说明 代码实现 <!DOCTYPE html> <html lang"en"> <head>…

十问华为云 Toolkit:开发插件如何提升云上开发效能

众所周知&#xff0c;桌面集成开发环境&#xff08;IDE&#xff09;已经融入到开发的各个环节&#xff0c;对开发者的重要性和广泛度是不言而喻的&#xff0c;而开发插件更是建立在IDE基础上的功能Buff。 Huawei Cloud ToolKit作为华为云围绕其产品能力向开发者桌面上的延伸&a…

快速实现SAP的移动化和流程优化

热门议题&#xff1a; 1、企业如何快速解决人员移动办公的需求&#xff0c;比如在苹果安卓手机&#xff0c;平板电脑&#xff0c;MAC登录SAP。2、企业如何解决用户经常抱怨的流程复杂&#xff0c;操作繁琐&#xff0c;难以使用等问题 公司介绍&#xff1a; Synactive,Inc. 是…

8. 实现业务功能--用户注册

目录 1. 顺序图 2. 参数要求 3. 接口规范 4. 创建扩展 Mapper.xml 5. 修改 DAO 6. 创建 Service 接口 7. 实现接口 8. 测试接口 9. 实现 Controller 9.1 密码加密处理 10. 实现前端界面 业务实现过程中主要的包和目录及主要功能&#xff1a; model 包&#xff1a;实体对象 d…

vue 弹出框 引入另一个vue页面

为什么要这么做,适用于在一个页面逻辑比较多的时候,可以搞多个页面,防止出错 index页面点击解约按钮,弹出框 进入jieyue.vue 核心代码 <el-buttonsize"mini"type"text"icon"el-icon-edit"v-if"scope.row.delFlag 0"click"j…

探索人工智能 | 模型训练 使用算法和数据对机器学习模型进行参数调整和优化

前言 模型训练是指使用算法和数据对机器学习模型进行参数调整和优化的过程。模型训练一般包含以下步骤&#xff1a;数据收集、数据预处理、模型选择、模型训练、模型评估、超参数调优、模型部署、持续优化。 文章目录 前言数据收集数据预处理模型选择模型训练模型评估超参数调…

websocker无法注入依赖

在公司中准备用websocker统计在线人数&#xff0c;在WebSocketServer使用StringRedisTemplate保存数据到redis中去&#xff0c;但是在保存的时候显示 StringRedisTemplate变量为null 详细问题 2023-08-20 10:37:14.109 ERROR 28240 --- [nio-7125-exec-1] o.a.t.websocket.po…

NAS个人云存储 - 手把手教你搭建Nextcloud个人云盘并实现公网远程访问

文章目录 摘要1. 环境搭建2. 测试局域网访问3. 内网穿透3.1 ubuntu本地安装cpolar3.2 创建隧道3.3 测试公网访问 4 配置固定http公网地址4.1 保留一个二级子域名4.1 配置固定二级子域名4.3 测试访问公网固定二级子域名 摘要 Nextcloud,它是ownCloud的一个分支,是一个文件共享服…