std:string 如何防止我不小心踩踏它的数据
How does std:string prevent me from carelessly stomping on its data?
我有以下C++代码:
#include <string>
#include <iostream>
int main(int argc, char** argv)
{
int size;
std::string strArray[3];
std::string str0 = "String 0";
std::string str1 = "String 1";
std::string str2 = "String 2";
strArray[0] = str0;
strArray[1] = str1;
strArray[2] = str2;
for (int i = 0; i < 3; i++)
{
std::cout << strArray[i] << std::endl;
}
str1.resize(200, 'a');
for (int i = 0; i < 3; i++)
{
std::cout << strArray[i] << std::endl;
}
std::cout << str1 << std::endl;
std::cin.get();
return 0;
}
这里的想法是,我有一个数组,它是一个连续的内存块,其中每个成员都是一个 std::string,它们是可变的,因此大小可变。我希望这段代码会中断,因为我调整 str1 的大小以占用比原始负载更多的空间,因此"溢出"到 str2 中。
相反,我得到这个输出:
字符串0
字符串1
字符串2
字符串0
字符串1
字符串2
String1aa
我对此有两个问题。首先,为什么增加 str1 的大小并向其添加字符负载不会流入 str2,即使它们应该在连续的内存块中?
其次,当我在调整 str1 大小并向其添加字符后第二次打印数组时,为什么它仍然打印原始 str1?我有一种感觉,这将与我的第一个问题的答案有关,但我不太明白这里发生了什么。
string
对象的数组是连续的,但实际的字符串数据存储在堆*上,因此字符串数据本身不是连续存储的。
* 实际上,给定一个使用"小字符串优化"的实现,数据是连续的,只要它足够小以适合,就存储在字符串对象中。"String0"对于我所知道的所有SSO实现来说都足够小。一旦数据增长到可以就地存储的内容,实现就会将其移动到堆上。
修改str1
不会影响打印strArray[1]
结果的原因是它们是没有关系的不同对象,只是您使用值初始化了strArray[1]
str1
。这就像做:
int intArray[3];
int int0 = 0;
int int1 = 1;
int int2 = 2;
intArray[0] = int0;
intArray[1] = int1;
intArray[2] = int2;
int1 = 10000000; // does not modify intArray[1]
这里的想法是,C++中对象的通常行为与您在其他语言中可能熟悉的"基元类型"或"值类型"相同。可以在C++中实现其他行为,但std::string
是常规类型。
正如 barnes53 指出的那样,string
数组只存储string
对象,并且可以简单地保存指向表示字符串的字符数组的指针。
第二个问题的答案是数组赋值是通过值而不是引用完成的,这意味着创建了字符串的副本。这就是为什么修改原始字符串对数组版本没有影响的原因。
数组是连续的,字符串不是。
你说str1.resize(200, 'a');
对数组没有影响,因为数组包含str1
过去不是reference
的value
。
因此,数组值不会溢出,因为数组中的值从未更改。
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如果用户不小心给出了不正确的数据类型,cin 如何工作?
- 使用 Broadcast 发出的从节点服务器发送的数据不能被 C++ 套接字 IO 客户端读取
- Winsock 数据不是从 IP 检索的,而是从普通 URL 检索的
- C++覆盖父结构中的数据不起作用
- 使用ifstream时,被调用文件中的数据不会打印
- C++/WinRT 数据 不正确的数据封送处理
- 数据不是用 ofstream 写入的,即使返回成功也是如此
- 为什么数据不传输
- 我不小心删除了 c++ Visual Studio 中的部分代码
- curl发送JSON数据不使用C 工作
- 为什么我的循环完整收集数据不在动态分配的数组中
- 我不小心删除了"winnt.h"如何找回它?
- 数据不会插入到指针数组中
- 为什么特征矩阵库的固定大小类型与积分数据不是 PoD?
- C 从文件中读取FSTREAM数据不会返回正确的值.inputfile.tellg返回-1
- 数据不匹配,编译器无法推断模板参数
- 为什么我的数据不适合CUDA纹理对象
- 为什么Visual C++ 2008在我(不小心)使用布尔类型时没有抱怨
- std:string 如何防止我不小心踩踏它的数据