#include <iostream>
#include <string>
static uint32_t s_AllocCount = 0;
// Overload of new operator.
void* operator new(size_t size) {
s_AllocCount++;
std::cout << "Allocating " << size << " bytes\n";
return malloc(size);
}
void PrintName(const std::string& name) {
std::cout << name << " - " << name.length() << " characters." << std::endl;
}
int main() {
std::string name = "123456789012345";
PrintName(name);
std::cout << s_AllocCount << " allocations" << std::endl;
std::cin.get();
}
上面的代码是 How to make your STRINGS FASTER in C++! 中的一个稍微修改过的版本。
我对这个程序在 x86 调试中编译的 Visual Studio 2019 中的各种输出感到困惑。
当std::string name = "123456789012345";
结果如下:
我知道为指针地址分配了 8 个字节。我不明白的是这个字符串中有 15 个字节。指针地址不是指向一个 8 字节的内存块,即可以容纳 8 个字符的内存块吗?
当std::string name = "1234567890123456";
时,即加长1个字符为16,结果为:
现在,额外分配了 32 字节的内存,显然足以容纳 16 个字符。
我的理解是否正确:
在第一种情况下,只有 8 个字节的堆内存被分配用于存储字符串的指针地址,并且字符串的 15 个字符被存储在堆栈上?
在第二种情况下,正在分配40字节的堆内存,并且两者字符串的指针地址和字符串字符都存储在堆上?
这个问题是由引用视频的作者关于在 OpenGL 中使用 std::string
提出的。具体来说,他建议在 OpenGL 中随意使用 std::string
可以大大减慢动态场景变化。现在,我正试图更好地了解分配了多少内存以及在何处分配,这样至少我知道什么时候它可能会减慢程序速度。
因为我稍微修改了这个程序,也许代码没有按照我的想法去做,也就是说,我犯了一个编程错误。如果是这样,我将不胜感激所发现的错误。
最佳答案
我不知道分配这 8 个字节的目的是什么,但假设是典型的 std::string
实现,则不需要任何动态分配。字符串实现实现“小字符串优化”:
想法是将字符串对象视为标记 union ,将指向动态字符串的指针集作为一个成员,将大小相等的字符数组作为另一个成员。只要字符串适合 sizeof(std::string)
,它就存储在该数组成员中;否则动态分配字符串,并存储指针。
- That in the first case only 8 bytes of heap memory are being allocated for storing the string's pointer address and that the 15 characters of the string are stored on the stack?
这 8 个字节可能与字符串没有直接关系。我没有看到动态存储“字符串的指针地址”的理由。指针的地址存储在哪里,会实现什么?相反,分配可能与某些调试功能有关。
将 15 个字符存储在堆栈中可能是准确的。
关于c++ - std::string 各种长度的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59035537/