当前位置: 首页 > 编程笔记 >

深入探究C++ string的内部究竟是什么样的

洪和风
2023-03-14
本文向大家介绍深入探究C++ string的内部究竟是什么样的,包括了深入探究C++ string的内部究竟是什么样的的使用技巧和注意事项,需要的朋友参考一下

在C语言中,有两种方式表示字符串:

  • 一种是用字符数组来容纳字符串,例如char str[10] = "abc",这样的字符串是可读写的;
  • 一种是使用字符串常量,例如char *str = "abc",这样的字符串只能读,不能写。

两种形式总是以\0作为结束标志。

C++ string 与它们在C语言中的前身截然不同。首先,也是最重要的不同点,C++ string 隐藏了它所包含的字符序列的物理表示。程序设计人员不必关心数组的维数或\0方面的问题。

string 在内部封装了与内存和容量有关的信息。具体地说,C++ string 对象知道自己在内存中的开始位置、包含的字符序列以及字符序列长度;当内存空间不足时,string 还会自动调整,让内存空间增长到足以容纳下所有字符序列的大小。

C++ string 的这种做法,极大地减少了C语言编程中三种最常见且最具破坏性的错误:

  • 数组越界;
  • 通过未被初始化或者被赋以错误值的指针来访问数组元紊;
  • 释放了数组所占内存,但是仍然保留了“悬空”指针。

C++ 标准没有定义 string 类的内存布局,各个编译器厂商可以提供不同的实现,但必须保证 string 的行为一致。采用这种做法是为了获得足够的灵活性。

特別是,C++ 标准没有定义在哪种确切的情况下应该为 string 对象分配内存空间来存储字符序列。string 内存分配规则明确规定:允许但不要求以引用计数(reference counting)的方式实现。但无论是否采用引用计数,其语义都必须一致。

C++ 的这种做法和C语言不同,在C语言中,每个字符型数组都占据各自的物理存储区。在 C++ 中,独立的几个 string 对象可以占据也可以不占据各自特定的物理存储区,但是,如果采用引用计数避免了保存同一数据的拷贝副本,那么各个独立的对象(在处理上)必须看起来并表现得就像独占地拥有各自的存储区一样。例如:

// #include<bits/stdc++.h>
#include <iostream>
#include <string>
using namespace std;
 
int main() {
 string s1("12345");
 string s2 = s1;
 cout << (s1 == s2) << endl;
 s1[0] = '6';
 cout << "s1 = " << s1 << endl; // 62345
 cout << "s2 = " << s2 << endl; // 12345
 cout << (s1 == s2) << endl;
 
 return 0;
}

在 GCC 下的运行结果:

1
s1 = 62345
s2 = 12345
0

只有当字符串被修改的时候才创建各自的拷贝,这种实现方式称为写时复制(copy-on-write)策略。当字符串只是作为值参数(value parameter)或在其他只读情形下使用,这种方法能够节省时间和空间。

不论一个库的实现是不是采用引用计数,它对 string 类的使用者来说都应该是透明的。遗憾的是,情况并不总是这样。在多线程程序中,几乎不可能安全地使用引用计数来实现。

到此这篇关于C++ string的内部究竟是什么样的的文章就介绍到这了,更多相关C++ string内部是什么内容请搜索小牛知识库以前的文章或继续浏览下面的相关文章希望大家以后多多支持小牛知识库!

 类似资料:
  • 内部构造函数的准确定义是什么?在Julia-V0.6+中,“任何可以使用签名(注意部分)调用的构造函数都是内部构造函数”是正确的吗? 正如下面的注释中所讨论的,仅限于外部的构造函数实际上是吗? 使用检查方法是否是内部/外部构造函数是否正确? Julia自动定义的默认构造函数与用户显式定义的相应构造函数有什么不同? 顺便说一句,我知道如何使用以及何时使用内部构造函数。我知道什么是内部构造函数,直到只

  • 主要内容:机械硬盘(HDD),固态硬盘(SSD)在 Linux 系统中,文件系统是创建在硬盘上的,因此,要想彻底搞清楚文件系统的管理机制,就要从了解硬盘开始。 硬盘是计算机的主要外部存储设备。计算机中的存储设备种类非常多,常见的主要有光盘、硬盘、U 盘等,甚至还有网络存储设备 SAN、NAS 等,不过使用最多的还是硬盘。 如果从存储数据的介质上来区分,硬盘可分为 机械硬盘(Hard Disk Drive, HDD)和 固态硬盘(Solid St

  • 问题内容: 我在jquery图像滑块演示中找到了reset.css文件,但它从未包含在主index.html文件中。应该做什么,更重要的是,您将它放在哪里?你把它之前 任何引用的样式表()? 这是reset.css内部的代码 问题答案: 最初,关于样式的工作方式还没有标准化,每个浏览器都实现了自己认为正确的方式。您在IE中看到太多有关样式错误的问题的原因之一是,因为IE是样式方面与其他浏览器最不相

  • 主要内容:C语言难吗?,C语言是计算机产业的核心语言对于大部分程序员,C语言是学习编程的第一门语言,很少有不了解C的程序员。 C语言除了能让你了解编程的相关概念,带你走进编程的大门,还能让你明白程序的运行原理,比如,计算机的各个部件是如何交互的,程序在内存中是一种怎样的状态,操作系统和用户程序之间有着怎样的“爱恨情仇”,这些底层知识决定了你的发展高度,也决定了你的职业生涯。 如果你希望成为出类拔萃的人才,而不仅仅是码农,这么这些知识就是不可逾越的。

  • 问题内容: 设置或设置为弹性项目而不是设置之间有区别吗? 是属性的“转折点” 吗? 当我设置浏览器时,如何确定将项目下移到新行的哪一点?是根据他们的宽度还是“弹性基础”? 示例:最后两个框具有相同的功能,但是当窗口在300px至400px之间时, 只有 其中一个向下移动。为什么? 问题答案: 允许您在计算其他任何内容之前指定元素的初始/开始大小。它可以是百分比或绝对值。 但是,它 不是 弯曲增长/

  • 本文向大家介绍深入探究Swift枚举关联值的内存,包括了深入探究Swift枚举关联值的内存的使用技巧和注意事项,需要的朋友参考一下 这是枚举最基础的用法,但是在swift中,对枚举的功能进行了加强,也就是关联值。 关联值可以将额外信息附加到 enum case中,像下面这样子。 我们可以看到,在我们创建一个枚举值t的时候,设置他的选项为test1,同时可以关联3个Int类型的值,然后在switch