c++ - 数组如何在 C++ 的内存中存储字符串?
问题描述
要访问数组中的任何随机索引,我们访问以下内存位置:
a[i] = 基地址 + (data_type 的大小) * i
这就是为什么数组只有相同类型的数据的原因。
现在,当我们使用 int、char 等原始数据类型时,这非常有效。
但是,假设我有一个字符串数组,其中每个字符串的大小不同:
string a[] = {"xyz", "abcde", "qwerty"}
这在内存中是如何工作的?由于每个字符串占用不同的内存,这在内部如何工作?
编辑 :
得到了字符串的答案。字符串在内部具有恒定的大小,因此可以解决。
在假设向量数组的情况下会发生什么:
vector<int> v[5];
它们内部是否也有恒定的大小?
解决方案
我会说字符串内存布局取决于实现,但通常应该有 15 个字节(对于短字符串实现)加上一个指针(对于更大的字符串)。所以一个数组std::string
将是一个固定大小、连续的字符串数组(在我的示例中,每个 15 个字节加上指针的大小,通常是 4 个字节)
你可以做这个简单的测试:打印数组中每个字符串的地址,然后打印每个字符串中第一个字符的地址。
#include <iostream>
#include <string>
int main()
{
std::string a[] = {
"Hey",
"There",
"The quick fox jumped over the brown dog",
"Bye!"
};
std::cout << a << "\n";
for (const auto& str : a)
{
std::cout << &str << "\n";
const int* ptr_to_first_char = reinterpret_cast<const int*>(&(str[0]));
std::cout << "\t" << ptr_to_first_char << "\n";
}
}
gcc 的结果:
0x7ffc46eef050
0x7ffc46eef060
0x7ffc46eef070
0x7ffc46eef080
0x7ffc46eef090
0x13e8eb0
0x7ffc46eef0b0
0x7ffc46eef0c0
- 您会看到实际上为每个字符串保留了 16 个字节。例如,在 ...f060,“Hey”中“H”的地址和 ...f070,地址之间
std::string("There")
。 - 您会看到其他 16 个字节也被保留,可能是为指向堆的指针,以防字符串大于 16 个字节。例如在 ...f070 和 ...f080 之间。
- 所有 0x7ffc... 地址都应该指向栈, 0x13e8... 地址应该指向堆。
推荐阅读
- docker-registry - 需要 Nexus OSS Docker 代理存储库身份验证
- python - Stripe Transfers:在没有适当费用的情况下创建传输以用作 source_transaction
- c - 我希望结果打印 ac[0] 但它给了我一个问号,如图所示。我能做些什么来纠正它?
- javascript - 提交带有加载数据的表单
- angular - 未收到来自跨模块订阅 observable 的事件
- c++ - 在 C++ Windows 中将图像文件从服务器发送到客户端
- r - 在 R 中的多个数据帧中查找每个单元格中的最大值
- javascript - 识别元素不存在 selenium webdriver javascript
- java - 如何在没有 java.util.Arrays 的情况下在 Java 中的两个数组中查找位置
- c++ - 为什么我的编译器不能按预期工作?