2.5 动态字符串 String (完整源码)
C++自学精简教程 目录(必读)
C++数据结构与算法实现(目录)
本文的实现基本上和 动态数组 vector 是一样的。
因为大部分接口都一样。
所以,本文就直接给出全部的源码和运行结果。
//------下面的代码是用来测试你的代码有没有问题的辅助代码,你无需关注------
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
struct Record { Record(void* ptr1, size_t count1, const char* location1, int line1, bool is) :ptr(ptr1), count(count1), line(line1), is_array(is) { int i = 0; while ((location[i] = location1[i]) && i < 100) { ++i; } }void* ptr; size_t count; char location[100] = { 0 }; int line; bool is_array = false; bool not_use_right_delete = false; }; bool operator==(const Record& lhs, const Record& rhs) { return lhs.ptr == rhs.ptr; }std::vector<Record> myAllocStatistic; void* newFunctionImpl(std::size_t sz, char const* file, int line, bool is) { void* ptr = std::malloc(sz); myAllocStatistic.push_back({ ptr,sz, file, line , is }); return ptr; }void* operator new(std::size_t sz, char const* file, int line) { return newFunctionImpl(sz, file, line, false); }void* operator new [](std::size_t sz, char const* file, int line)
{return newFunctionImpl(sz, file, line, true);
}void operator delete(void* ptr) noexcept { Record item{ ptr, 0, "", 0, false }; auto itr = std::find(myAllocStatistic.begin(), myAllocStatistic.end(), item); if (itr != myAllocStatistic.end()) { auto ind = std::distance(myAllocStatistic.begin(), itr); myAllocStatistic[ind].ptr = nullptr; if (itr->is_array) { myAllocStatistic[ind].not_use_right_delete = true; } else { myAllocStatistic[ind].count = 0; }std::free(ptr); } }void operator delete[](void* ptr) noexcept { Record item{ ptr, 0, "", 0, true }; auto itr = std::find(myAllocStatistic.begin(), myAllocStatistic.end(), item); if (itr != myAllocStatistic.end()) { auto ind = std::distance(myAllocStatistic.begin(), itr); myAllocStatistic[ind].ptr = nullptr; if (!itr->is_array) { myAllocStatistic[ind].not_use_right_delete = true; } else { myAllocStatistic[ind].count = 0; }std::free(ptr); } }
#define new new(__FILE__, __LINE__)
struct MyStruct { void ReportMemoryLeak() { std::cout << "Memory leak report: " << std::endl; bool leak = false; for (auto& i : myAllocStatistic) { if (i.count != 0) { leak = true; std::cout << "leak count " << i.count << " Byte" << ", file " << i.location << ", line " << i.line; if (i.not_use_right_delete) { cout << ", not use right delete. "; } cout << std::endl; } }if (!leak) { cout << "No memory leak." << endl; } }~MyStruct() { ReportMemoryLeak(); } }; static MyStruct my;
//------上面的代码是用来测试你的代码有没有问题的辅助代码,你无需关注------//------check用来检查有没有bug begin------
#include <iostream>
using namespace std;
void check_do(bool b, int line = __LINE__) { if (b) { cout << "line:" << line << " Pass" << endl; } else { cout << "line:" << line << " Ohh! not passed!!!!!!!!!!!!!!!!!!!!!!!!!!!" << " " << endl; exit(0); } }
#define check(msg) check_do(msg, __LINE__);
//------check用来检查有没有bug end------class String
{friend std::ostream& operator<<(std::ostream& os, const String& str);
public:String(void);String(const char* data, int length);String(const char* data);String(const String& from);//1 复制构造String& operator = (const String& from);//2 赋值操作符size_t size(void) const { return m_length; }bool empty(void) const { return m_length == 0; }~String();//3 析构函数bool operator == (const String& other);bool operator != (const String& other) { return !(*this == other); }String operator+(const String& other);void push_back(char c);void clear(void);protected:void copy(const char* data, size_t length);
private:char* m_data;size_t m_length;int m_capacity = 0;
};
void String::push_back(char c)
{if (m_capacity > m_length)//直接追加到最后一个{m_data[m_length++] = c;}else//只有满了的那一瞬间,才翻倍开辟新空间{m_capacity = (m_capacity == 0 ? 10 : m_capacity + m_capacity);auto pNewArray = new char[m_capacity];//拷贝老数据for (size_t i = 0; i < m_length; i++){pNewArray[i] = m_data[i];}//追加最新的末尾元素pNewArray[m_length++] = c;delete[] m_data;m_data = pNewArray;}
}
std::ostream& operator<<(std::ostream& os, const String& str)
{for (size_t i = 0; i < str.m_length; ++i){os << str.m_data[i];}return os;
}
String::String(void) :m_data(nullptr), m_length(0)
{
}
String::~String()
{clear();
}
bool String::operator==(const String& other)
{if (other.m_length != this->m_length){return false;}for (size_t i = 0; i < m_length; i++){auto c1 = m_data[i];auto c2 = other.m_data[i];if (c1 != c2){return false;}}return true;
}
String String::operator+(const String& other)
{if (other.empty()){return *this;}String result;result.m_length = m_length + other.m_length;result.m_data = new char[result.m_length];for (size_t i = 0; i < m_length; i++){result.m_data[i] = m_data[i];}for (size_t i = 0; i < other.m_length; i++){result.m_data[m_length + i] = other.m_data[i];}return result;
}
String::String(const char* data, int _length) :m_data(nullptr), m_length(0)
{copy(data, _length);
}
String::String(const char* data) : m_data(nullptr), m_length(0)
{int stringLength = 0;auto p = data;while (*p != '\0'){++stringLength;++p;}copy(data, stringLength);
}
String::String(const String& from) : m_data(nullptr), m_length(0)
{if (from.m_data != m_data){copy(from.m_data, from.m_length);}
}
String& String::operator=(const String& from)
{if (&from != this){copy(from.m_data, from.m_length);}return *this;
}void String::clear(void)
{if (nullptr != m_data){delete[] m_data;m_data = nullptr;m_length = 0;}
}
void String::copy(const char* data, size_t length)
{clear();m_data = new char[length];for (size_t i = 0; i < length; ++i){m_data[i] = data[i];}m_length = length;
}String GetLeftValue(void)
{String s("String");return s;
}
void Test0(void)
{auto leftValue1 = GetLeftValue();String left2;left2 = (left2 = leftValue1);std::vector<String> arrStr(2);left2 = (arrStr[0]);String arr[2];left2 = (arr[0]);auto p = arr;left2 = (*p);arrStr.push_back(left2);
}
void Test_empty(void)
{String s("");check(s.empty());check(s.size() == 0);check(s == "");
}
void Test_clear(void)
{String s2;{String s("123");check(s == "123");s2 = s;s.clear();s.clear();check(s.size() == 0);check(s.empty());check(s == "");check(s2 != s);}check(s2 == "123");
}
void Test_copy(void)
{{String s1("Hello World!");//constructorString s2(s1);//copy constructorcout << s2 << endl;//operator<<check(s1.size() == s2.size());//sizeString s3;s3 = s2;check(s3 == s1);check(!s3.empty());check(!s1.empty());s1 = s2 = s2 = s1;check(s1.size() == s2.size());//sizecheck(s3 == s1);check(!s3.empty());check(!s1.empty());check(s1 == "Hello World!");s1.clear();check(s1.empty());check(s1 != s2);check(s2 == s3);}{String s;check(s.empty());}// +{String s1("Hello World!");//constructorString s2("Hello World!");//constructorString s3(s1 + s2);check(s3.size() == s1.size() + s2.size());check(s3 == s1 + s2);check(s3 == "Hello World!Hello World!");}{const char* p = "Hello World !";String s(p);check(s == p);}//push_back{String s;check(s.size() == 0);check(s.empty());s.push_back('a');check(s == "a");for (size_t i = 0; i < 100; i++){s.push_back('a');}check(s.size() == 101);}
}String GetValue(void)
{String a;String b;b = a;return a;
}int main()
{Test0();Test_empty();Test_copy();Test_clear();return 0;
}
正确的运行结果:
line:194 Pass
line:195 Pass
line:196 Pass
Hello World!
line:220 Pass
line:223 Pass
line:224 Pass
line:225 Pass
line:227 Pass
line:228 Pass
line:229 Pass
line:230 Pass
line:231 Pass
line:233 Pass
line:234 Pass
line:235 Pass
line:239 Pass
line:246 Pass
line:247 Pass
line:248 Pass
line:253 Pass
line:258 Pass
line:259 Pass
line:261 Pass
line:266 Pass
line:203 Pass
line:207 Pass
line:208 Pass
line:209 Pass
line:210 Pass
line:212 Pass
Memory leak report:
No memory leak.
欢迎参考借鉴,如有问题欢迎评论指出!
祝你好运!
相关文章:
2.5 动态字符串 String (完整源码)
C自学精简教程 目录(必读) C数据结构与算法实现(目录) 本文的实现基本上和 动态数组 vector 是一样的。 因为大部分接口都一样。 所以,本文就直接给出全部的源码和运行结果。 //------下面的代码是用来测试你的代码有没有问题的辅助代码…...

Ansible之变量
一)Ansible变量介绍 我们在PlayBook⼀节中,将PlayBook类⽐成了Linux中的shell。 那么它作为⼀⻔Ansible特殊的语⾔,肯定要涉及到变量定义、控 制结构的使⽤等特性。 在这⼀节中主要讨论变量的定义和使⽤ 二)变量命名规则 变量的…...

自动化测试面试常见技术题目
1:一行代码实现1--100之和 print(sum(list(range(1,101)))) 2:如何在一个函数内部修改全局变量 global 修改全局变量 局部作用域只能调用全局作用域的变量,但是不熊修改全局作用域的变量,如果想要修改全局作用域的变量需要gl…...

aarch64 arm64 部署 stable diffusion webui 笔记 【2】继续安装其他依赖 gfpgan
接上篇 aarch64 arm64 部署 stable diffusion webui 笔记 【1】准备 venv 安装pytorch 验证cuda_hkNaruto的博客-CSDN博客 编辑requirements_versions.txt,注释掉torch 启动webui.sh (venv) [rootceph3 stable-diffusion-webui]# useradd yeqiang useradd…...

使用ECS和RDS部署WordPress,搭建个人博客并使用域名访问
目录 一、准备工作 1、准备ECS服务器 2、创建数据库账号和密码 二、部署环境 1、远程连接 2、安装Apache服务 3、部署WordPress 三、对博客的优化并使用域名访问 1、博客的设计优化 1.1 插件的使用 1.2 博客的设计介绍 2、使用域名访问 四、个人博客部署的心得 1…...

C# Winform 简单排期实现(DevExpress TreeList)
排期的需求在很多任务安排的系统中都有相应的需求,原生的Winform控件并未提供相应的控件,一般都是利用DataGridViewTreeView组合完成相应的需求,实现起来比较麻烦。用过DevExpress控件集的开发者应该知道,DevExpress WinForm提供了…...
2023高教社杯国赛数学建模C题思路+模型+代码(9.7晚开赛后第一时间更新)
目录 1.C题思路模型:9.7晚上比赛开始后,第一时间更新,获取见文末名片 2.竞赛注意事项:包括比赛流程,任务分配,时间把控,论文润色,已经发布在文末名片中 3.常用国赛数学建模算法 …...

QT6中添加串口模块SerialPort最简单方法
qt6.2.3以上版本已经开始支持SerialPort包了,不用在傻傻的自己去编译包了。 在安装的时候勾选SerialPort即可。 等着安装完即可。 如果已经安装完了的小伙伴,可以用 从新打开维护 选择增加或者删除组件 即可从新选择组件...

LeetCode每日一题:1123. 最深叶节点的最近公共祖先(2023.9.6 C++)
目录 1123. 最深叶节点的最近公共祖先 题目描述: 实现代码与解析: dfs 原理思路: 1123. 最深叶节点的最近公共祖先 题目描述: 给你一个有根节点 root 的二叉树,返回它 最深的叶节点的最近公共祖先 。 回想一下&…...
Oracle查看锁表和正在执行的Sql
查看当前被锁的表(需要有管理员权限): --查看锁表进程SQL语句1: select sess.sid,sess.serial#,lo.oracle_username,lo.os_user_name,ao.object_name,lo.locked_modefrom v$locked_object lo, dba_objects ao, v$session sesswh…...
Linux centos 卸载 ceph
在CentOS上卸载Ceph的操作步骤: 1. 停止Ceph集群:首先,你需要停止Ceph集群中的所有服务。在每个节点上运行以下命令来停止所有服务 systemctl stop ceph.target 2. 卸载Ceph软件包:在每个节点上,使用yum包管理器卸载C…...
ElementUI浅尝辄止34:Radio 单选框
在一组备选项中进行单选 1.如何使用? 由于选项默认可见,不宜过多,若选项过多,建议使用 Select 选择器。 //要使用 Radio 组件,只需要设置v-model绑定变量,选中意味着变量的值为相应 Radio label属性的值&…...

开始MySQL之路——MySQL三大日志(binlog、redo log和undo log)概述详解
前言 MySQL实现事务、崩溃恢复、集群的主从复制,底层都离不开日志,所以日志是MySQL的精华所在。只有了解MySQL日志,才算是彻底搞懂MySQL。 日志是mysql数据库的重要组成部分,记录着数据库运行期间各种状态信息。mysql日志主要包…...
router基础使用
1.安装router npm i vue-router3 安装后 2.写出路由界面 接着 3.配置路由 import Vue from vue import VueRouter from vue-router import Home from "../views/Home.vue" import About from "../views/About.vue" Vue.use(VueRouter)const routes …...

亚马逊云科技人工智能内容审核服务:大大降低生成不安全内容的风险
生成式人工智能技术发展日新月异,现在已经能够根据文本输入生成文本和图像。Stable Diffusion是一种文本转图像模型,可以创建栩栩如生的图像应用。通过Amazon SageMaker JumpStart,使用Stable Diffusion模型轻松地从文本生成图像。 尽管生成式…...

2023年高教社杯数学建模思路 - 案例:最短时间生产计划安排
文章目录 0 赛题思路1 模型描述2 实例2.1 问题描述2.2 数学模型2.2.1 模型流程2.2.2 符号约定2.2.3 求解模型 2.3 相关代码2.4 模型求解结果 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 最短时…...
算法工程题(二叉树递归)
* 题意说明: * 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 * 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 * * 示例 1: * 输入:p [1,2,3]…...

“指针跃动”受邀参加全球贸易服务峰会
“指针跃动”受邀参加全球贸易服务峰会 有“服”同享 共赢未来 引子 在全球化日益盛行的今天,贸易不再仅仅是物质的交流,更涉及到服务、理念、文化和科技的共享。中国国际服务贸易交易会全球贸易服务峰会,就是这个趋势的集中体现。在这次峰会…...
Go Web开发的高级技巧和最佳实践
Go Web开发的高级技巧和最佳实践 欢迎来到Go语言Web开发的高级技巧和最佳实践指南。在这篇文章中,我们将深入探讨Go语言Web应用程序的高级主题,包括性能优化、安全性、部署和微服务架构。 性能优化 性能是Web应用程序的关键因素之一。Go语言以其出色的…...

Verilog 基础知识
1、数值种类 Verilog HDL 有下列四种基本的值来表示硬件电路中的电平逻辑: 0:逻辑 0 或 “假”1:逻辑 1 或 “真”x 或 X:未知 x 意味着信号数值的不确定,即在实际电路里,信号可能为 1,也可能…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...

算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...

【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...