[c++] char * 和 std::string

1 char * 和 std::string 的区别

char * 字符串是常量字符串,不能修改;std::string 指向的字符串可以修改

实例代码如下图所示,s1 和 s2 均是常量字符串,字符串常量保存在只读数据区,是只读的,不能写,代码中注释的那两行代码会导致段错误。

s3 是字符数组,字符数组是可以修改的,std::string 类型的字符串也是可以修改的。

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <cstring>

int main() {
  char *s1 = "hello";
  char *s2 = "hello";
  char s3[] = "hello";
  std::string s4 = "hello";

  printf("s1 addr = %p, s2 addr = %p, s3 addr = %p, s4 addr = %p\n", s1, s2, s3, s4.c_str());
  printf("sizeof(s1) = %d, sizeof(s3) = %d, sizeof(s4.c_str()) = %d\n", sizeof(s1), sizeof(s3), sizeof(s4.c_str()));
  // s1[1] = 'a';
  // s2[1] = 'a';
  s3[1] = 'a';
  s4[1] = 'a';
  std::cout << "s1 = " << s1 << ", s2 = " << s2 << ", s3 = " << s3 << ", s4 = " << s4 << std::endl;
  return 0;
}

代码运行之后,可以看到 s1 和 s2 是常量字符串,这两个指针指向的地址也是相同的。

从 s1,s2 的地址和 s3,s4 的地址对比可以看出,s3 和 s4 的地址相距比较近,和 s1、s2 的地址相距比较远。s1、s2 和 s3、s4 保存的段都不一样,前者保存在只读数据段,后者保存在栈,所以地址差距才会大。 

2 std::string 是深度拷贝

如下图所示, 有 3 个字符串,s1、s2 和 s3。

s2 是基于 s1 通过拷贝构造而来,将 s2[1] 赋值为 'a',然后打印 s1 和 s2,s1 仍为 "hello",s2 为 "hallo",说明 s1 和 s2 相互不影响,是深拷贝。

s3 被 s1 赋值,将 s3[1] 赋值为 'm',然后打印  s1 和 s3,s1 仍为 "hello",s3 为 "hmllo",s1 和 s3 相互没有影响。 

#include <iostream>
#include <string>

int main() {
  std::string s1 = "hello";
  std::string s2 = s1;

  std::cout << "1, s2 = " << s1 << std::endl;
  s2[1] = 'a';
  std::cout << "2, s2 = " << s2 << ", s1 = " << s1 << std::endl;

  std::string s3 = "aaa";
  s3 = s1;
  std::cout << "1, s3 = " << s3 << std::endl;
  s3[1] = 'm';
  std::cout << "2, s3 = " << s3 << ", s1 = " << s1 << std::endl;
  return 0;
}

运行结果如下:

3 std::string capacity()

如下代码,声明了一个空字符串 s1,打印出来了 s1.capacity() 是 15,也就是说 std::string 默认就会有 15 的空间。如果字符串的大小不大于 15,就不会申请堆空间,如下代码可以验证。

 

 执行结果:

使用 gdb 调试,对 malloc 设置断点,可以查看上边的代码哪一行调用了 malloc()。

第 11 行:

字符串长度是 16,大于 15 了,需要申请内存。

第 12 行:

拷贝构造,深拷贝,长度大于 15,需要申请内存。

 

第 14 行:

赋值运算符,长度大于 15,需要申请内存。

第 16 行:

新创建的 s6,长度大于 15,需要申请空间。

 

代码第 17 行,将 s4 赋值给 s6,虽然 s4 的长度大于 15,但是当前 s6 的 capacity() 是 20,完全能够放得下 s4,所以不需要再申请空间。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QT GUI编程常用控件学习

1 GUI编程应该学什么 2 QT常用模块结构 QtCore: 包含了核心的非GUI的功能。主要和时间、文件与文件夹、各种数据、流、URLs、mime类文件、进程与线程一起使用 QtGui: 包含了窗口系统、事件处理、2D图像、基本绘画、字体和文字类 QtWidgets: 包含了一些列创建桌面应用的UI元素…

python input 输入

input()函数包含四个方面&#xff1a;input()函数的使用/结果的赋值/数据类型/结果的强制转换。是实现人机互动沟通的关键&#xff0c;需要在终端出输入信息。我们可以把input()函数当作一扇链接现实世界与代码世界的门&#xff0c; 如下图 先看一个例子&#xff1a;  运行后终…

生产线辅料加注机加注量的可视化操作系统无线通讯应用

挖掘机装配生产线在生产过程中&#xff0c;需要在下车装配、液压测试、发动机部件装配等过程中添加液压油、柴油、润滑油、防冻液、冷媒等辅料。加注机作为必要的辅料加注设备&#xff0c;将设定辅料输入到挖掘机对应输送管道中。 客户需求是想实现挖掘机装配线加注机与操作台…

Linux基础命令—系统服务

基础知识 centos系统的开机流程 1)通电 2)BIOS硬件检查 3)MBR引导记录 mbr的引导程序 加载引导程序 让硬件加载操作系统内核 MBR在第一个磁盘第一个扇区 总大小512字节 mbr: 1.引导程序: 占用446字节用于引导硬件,加载引导程序 2.分区表: 总共占…

关系型数据库事务的隔离级别: 读未提交, 读已提交, 可重复读, 序列化。

关系型数据库事务的隔离级别&#xff1a; 读未提交, 读已提交, 可重复读, 序列化。 事务的四性: 原子性&#xff0c;一致性&#xff0c;隔离性&#xff0c;持久性。(4项) 事务的隔离级别&#xff1a; 读未提交, 读已提交, 可重复读, 序列化。(4项) 并发事务可能引起: 脏读, …

【计算机网络】1.4 接入网和物理媒体

1.4 接入网和物理媒体 问题&#xff1a;怎样将端系统和边缘路由器连接&#xff1f; 答&#xff1a;有线方式&#xff08;住宅接入网络、单位接入网络等&#xff09;或无线方式&#xff08;无线接入网络&#xff09;。 有线接入方式 光纤同轴混合网是基于已有的有线电视网开发的…

中年人,收起你的大方

作者| Mr.K 编辑| Emma 来源| 技术领导力(ID&#xff1a;jishulingdaoli) 先和大家分享一件最近发生在K哥身上的真实故事。K哥前同事老G托我帮他一位朋友推荐工作&#xff0c;说他的这个朋友失业好几个月了&#xff0c;上有老下有小很不容易&#xff0c;让我无论如何也要想办…

IDEA安装配置以及安装配置Maven

IEDA官方下载地址&#xff0c;有专业版&#xff08;收费&#xff0c;破解&#xff09;&#xff0c;社区版&#xff08;免费&#xff09; 下载 IntelliJ IDEA – 领先的 Java 和 Kotlin IDE 安装配置Maven 1.解压apache-maven-3.6.3-bin.zip&#xff0c;安装maven到D盘softwar…

【YOLO v5 v7 v8小目标改进】SPD-Conv

SPD-Conv 提出背景SPD-Conv YOLO v5 小目标改进定义 SPD-Conv导入SPD模块修改 .yaml 文件 YOLO v7 小目标改进YOLO v8 小目标改进 提出背景 论文&#xff1a;https://arxiv.org/pdf/2208.03641v1.pdf 代码&#xff1a;https://github.com/labsaint/spd-conv 文章提出一个新的…

代码随想录算法刷题训练营day23

代码随想录算法刷题训练营day23&#xff1a;LeetCode(669)修剪二叉搜索树、LeetCode(108)将有序数组转换为二叉搜索树、LeetCode(538)把二叉树转化为累加树 LeetCode(669)修剪二叉搜索树 题目 代码 /*** Definition for a binary tree node.* public class TreeNode {* …

数据安全之路:深入了解MySQL的行锁与表锁机制

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 数据安全之路&#xff1a;深入了解MySQL的行锁与表锁机制 前言基础innodb中锁与索引的关系如何避免表锁 前言 在当今数据密集的应用中&#xff0c;数据库锁成为了确保数据一致性和并发操作的关键工具…

Linux字符设备驱动中同类型多设备节点的创建---一个驱动程序支持多个同类型设备

文章目录 前言1 代码解析1.1 驱动层1.2 应用层 2 运行结果总结 前言 本期分享的内容相对比较简单&#xff0c;那就是同时注册多个同类型的字符设备驱动&#xff0c;那么这样我们就可以同时支持多个同类型的设备了&#xff01;下面来带大家看一下&#xff1a; 1 代码解析 1.1 …

【Flink精讲】Flink性能调优:内存调优

内存调优 内存模型 JVM 特定内存 JVM 本身使用的内存&#xff0c;包含 JVM 的 metaspace 和 over-head 1&#xff09; JVM metaspace&#xff1a; JVM 元空间 taskmanager.memory.jvm-metaspace.size&#xff0c;默认 256mb 2&#xff09; JVM over-head 执行开销&#xff1…

深入探讨基于大语言模型的数据标注

文章地址&#xff1a; https://arxiv.org/pdf/2402.13446 数据标注是将原始数据用相关信息进行标注&#xff0c;对于提高机器学习模型的效果至关重要。然而&#xff0c;这一过程往往需要大量人力和资金支持。先进大语言模型&#xff08;LLMs&#xff09;的出现&#xff0c;例如…

小程序--事件处理

一、事件对象 给小程序的事件传递参数&#xff0c;有以下两种方法&#xff1a; 1、自定义属性 <view class"item" wx:for"{{ 5 }}" wx:key"*this" data-index"{{index}}" bind:tap"onClick"></view> Page({o…

spss常用检验方法

spss常用检验方法 1 数据是否符合正态分布1.1符合正态分布1.1.1怎样的数据符合正态分布1.1.2 spss怎么统计正态分布1.1.3 方差齐性检验1.1.4 具体统计学分析 1.2 不符合正态分布1.2.1 Mann-Whitney U检验1.2.2 Wilcoxon符号秩检验1.2.3 Kruskal-Wallis H检验1.2.4 Friedman检验…

CCF-CSP: 因子化简(100分)

第一次提交的时候90分&#xff0c;显示的超时&#xff0c;第一反应是难道有死循环? 检查一遍发现并没有&#xff0c;那就是真的超时了&#xff0c;然后翻阅blog,发现不需要去做判断是否是素数这一步&#xff0c;原因是任意一个非素数都是素数乘积构成&#xff0c;比如说&#…

提高移动应用的安全性:策略与实践

提高移动应用的安全性&#xff1a;策略与实践 随着移动应用的普及&#xff0c;安全性问题变得日益重要。用户数据保护、应用逻辑安全、以及防止恶意攻击都是开发者必须关注的重点。本文将探讨如何通过一系列策略和实践来提高移动应用的安全性。 1. 数据加密与保护 敏感数据加…

ABAP - Function ALV 05 添加选择框列、全选、取消全选

很多用户不习惯原生GRID的选择模式&#xff0c;所以业务需要用到自定义的选择框来进行数据的操作&#xff0c;显示效果如图所示&#xff0c;增加一条选择列&#xff0c;且配置全选和全选全选的按钮功能&#xff0c;如下图所示。 实现这种功能需要用到Fieldcat的参数控制以及GUI…

c#高级-正则表达式

正则表达式是由普通字符和元字符&#xff08;特殊符号&#xff09;组成的文字形式 应用场景 1.用于验证输入的邮箱是否合法。 2.用于验证输入的电话号码是否合法。 3.用于验证输入的身份证号码是否合法。等等 正则表达式常用的限定符总结&#xff1a; 几种常用的正则简写表达式…