首页 > 编程语言 >【c++经典面试题】有关string类的深浅拷贝

【c++经典面试题】有关string类的深浅拷贝

时间:2024-07-22 21:29:25浏览次数:11  
标签:面试题 string len c++ str 拷贝 size arey

题目背景

基于自实现string类substr成员函数时遇到的问题。

代码展示

string string::substr(size_t pos, size_t len) //声明时len的参省值位npos
	{
		assert(pos < _size);
		if (len > _size - pos) // 如果len的长度大于有效字符长度,那么重置为有效字符长度	
		{
			len = _size - pos;
		}
		string arey;
		arey.reserve(len);
		for (int i = 0; i < len; ++i)
		{
			arey += _str[pos + i];
		}
		return arey;
	}```

运行结果(仅在vs2019版本及以下会显现出来):

在这里插入图片描述
从这里,面试题就开始了。

面试提问

解释为什么会发生上述状况
从代码出发分析,substr函数的返回值为string,也就是传值返回,我们清楚地知道当传值返回一个类对象时会创建一个临时变量拷贝arey,再把arey拷贝给局部变量

在这里插入图片描述

vs2019以及低版本地编译器在debug的优化下,会跳过创建临时变量,直接把arey拷贝给局部变量,那么既然substr的逻辑没有问题,那么问题是否是出现在拷贝构造函数?

在这里插入图片描述

调试发现,arat的地址和局部变量的地址是一样的,那么也就说明着,aray只是单纯的把_str中存储的字符串的地址传给了局部变量,而当substr调用完成后,_str又会被销毁,那么就会造成内存泄漏,从而引发上述状况。

这也就是所谓的浅拷贝

解决问题

如何解决上述问题,那就是自己写一个显式拷贝构造函数。

拷贝构造函数代码

		string(const string& s)
		{
			_str = new char[s._capacity + 1];
			strcpy(_str, s._str);
			_size = s._size;
			_capacity = s._capacity;
		}

至此,问题将得以解决

注意

文中所展示的bug仅仅出现在低版本,优化不激进的情况下,若使用vs2019的release的情况下,也不会出现此状况。此时,编译器的优化更为激进,合三为一。

编译器直接构造给局部变量 !!!nb!

这里是引用

标签:面试题,string,len,c++,str,拷贝,size,arey
From: https://blog.csdn.net/Moment124/article/details/140619247

相关文章

  • c++(0) sophus矩阵转换
     1安装sophus2使用代码2-1R,t矩阵q四元数转换so3和se3 CMakeLists.txtcmake_minimum_required(VERSION3.0)project(useSophus)#为使用sophus,需要使用find_package命令找到它find_package(SophusREQUIRED)#Eigeninclude_directories("/usr/include/eigen3"......
  • Android 常见面试题(一)
    Android常见面试题(一)1、java中==和equals和hashCode的区别基本数据类型的==比较的值相等.类的==比较的内存的地址,即是否是同一个对象。在不重写equals方法的情况下,equals同比较内存地址,原实现也为==,如String等重写了equals方法,会判断字符串里的值是否相等......
  • c++零基础知识要点整理(7)
    *请搭配c++零基础知识要点整理(5)使用位或运算符的应用: | (有1即1)1.设置标记位(使某一个位置的值变为1)inta=0b101101;//(以使第五位变为1举例,即使a变为:0b11101)cout<<(a|0b10000)<<endl;//要使第五个位置的值变为1,则将这个数和0b10000进行位或//以此类推:需要使第四个......
  • C++树的介绍
    目录树的基本概念和术语树的种类实现树的例子遍历树在C++中,树(Tree)是一种非常重要的数据结构,用于模拟具有层级关系的数据。树结构是递归定义的,一个树由零个或多个节点(node)组成,其中一个节点被称为根节点(rootnode),其余节点分为若干个不相交的子树(subtree),每个子树也是一棵树......
  • django相关面试题
    1.auto_add与auto_add_now作用于时间类型的字段,auto_add_now只在创建数据的时候生效,auto_now在修改数据的时候生效create_time=models.DateTimeField(auto_now_add=True)update_time=models.DateTimeField(auto_now=True)注意这两个属性只有在使用django的orm的create......
  • jvm面试题
    目录1.jvm如何加载一个类?JVM加载类的过程双亲委派模型自定义类加载器2.jvm如何初始化一个类JVM类初始化过程3.剖析类始化Java类初始化的详细过程类初始化的触发条件父类与子类的初始化顺序注意事项1.jvm如何加载一个类?JVM加载类的过程Java虚拟机(JVM)加载类的过......
  • 聊聊C++string
    原文链接聊聊c++string  相信大家对string都不陌生,但不知道大家有没有这样的疑问:两个string之间赋值,是指向同一个字符串还是不同的字符串?  如果是深拷贝,按理说要指向不同的字符串,那么内部数据的地址要不同;如果是浅拷贝,怎么避免指针doublefree的问题?  先看个简单......
  • zig vs c++:控制x11鼠标移动
    zigDebug输出大小:2.3MBReleaseSmall输出大小:11.3kBconststd=@import("std");constx11=@cImport({@cInclude("X11/Xlib.h");});//Convertsbetweennumerictypes:.Enum,.Intand.Float.pubinlinefnas(comptimeT:type,from:anyty......
  • C++ 学习笔记十一 封装
    封装4.1.1封装的意义封装是C++面向对象三大特性之一封装的意义:将属性和行为作为一个整体,表现生活中的事物将属性和行为加以权限控制封装意义一:​在设计类的时候,属性和行为写在一起,表现事物语法:class类名{访问权限:属性/行为};**示例1:**设计一个圆类,求圆的周......
  • 手写Kd树(C++模板非递归实现)
    手写Kd树(C++模板非递归实现)1.Kd树1.1Kd树简介1.2Kd树的建立1.3Kd树的查找2.C++完整代码实现3.测试代码3.1代码实现3.2测试结果4.与PCL中的Kd树做对比本文实现的Kd树实现参考了高翔博士的书《自动驾驶与机器人中的slam技术从理论到实践》;高博士原书中是递归......