c++ - 计算 std::string 的分配内存(以及 std::vector 中字符串的使用)

标签 c++ string memory sizeof allocation

我想计算当我创建字符串并将值分配给字符串时分配了多少内存。

string s = "";
cout << sizeof(s) << endl;
cout << sizeof(s.at(0)) * s.capacity() << endl;
s = "1234567890qwertz";
cout << sizeof(s) << endl;
cout << sizeof(s.at(0)) * s.capacity() << endl;

这就是我的字符串 s 消耗的所有内存吗?我通过简单地调用 sizeof(s) 获得的初始/静态部分(在我的机器上为 40 字节)加上动态部分 - 一个字符的大小乘以分配的占位符,以使字符串有效地调整大小(在我的机器上,字符串 s 首先分配了一个 15 字节的 block ,直到文本太长为止,因此在第二次分配之后,动态部分是 31 字节)。顺便问一下,为什么不是 16 和 32 字节呢?

这种思考方式(每个字符串的静态+动态就是它所占用的全部内存)正确吗?

这意味着,如果我有一个字符串 std::vector,并且我也想计算该 vector 的所有内存,我需要做同样的事情:我添加我的字符​​串的初始/静态大小 vector 来获取加动态部分,这意味着一个字符串占用的总内存,就像我上面为 vector 内的每个字符串所做的那样?

vector<string> cache;
// fill cache with strings of dynamic length
int size = sizeof(cache);
for (int i = 0; i < cache.size(); i++)
{
    size += sizeof(cache[i]);
    size += sizeof(cache[i].at(0)) * cache[i].capacity();
}

总而言之,我的“缓存”占用的内存量是否正确?

编辑: 或者我是否还需要考虑到 std::vector 本身也有 .capacity() >= .size() 这可能意味着我实际上需要这样做:

对于每个 cache.capacity() - 我需要添加 sizeof(cache[i]) 并且另外 对于每个 cache.size() - 添加 sizeof(cache[i].at(0)) * cache[i].capacity() ??

最佳答案

这个问题很难回答。天真地你会认为消耗的内存总量是

vector_capacity * sizeof(std::string) + sum_of_capacity_of_each_string_in_the_vector

但这更多的是一个上限,而不是实际可以消耗的量。例如,short string optimization允许 std::string 将字符串数据存储在字符串对象本身消耗的存储空间中(即所谓的静态大小)。如果是这样的话,那么实际消耗的空间将是

vector_capacity * sizeof(std::string)

vector 中每个字符串的容量就是在不分配任何额外空间的情况下占用的空间大小。您需要检查您的实现,看看它是否使用 SSO 以及它将存储在字符串对象中的字符串长度,以实际了解容量值是否正在使用字符串内部空间或实际上消耗了额外的内存。这使得实际消耗的空间

vector_capacity * sizeof(std::string) + sum_of_capacity_of_each_string_in_the_vector_where_
                                        the_capcity_is_more_than_the_sso_amount

在您的计算中,不需要sizeof(cache[i].at(0))std::string 使用 charsizeof(char) 保证为 1

关于c++ - 计算 std::string 的分配内存(以及 std::vector 中字符串的使用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54237428/

相关文章:

c++ - 捕获参数包的拷贝

ios - NSString 子串检测

c++ - 调用特定于类的运算符 new

c++ - 报告对象正在使用堆栈/堆上的多少内存? (广发局)

python - Python中的多处理内存错误

c++ - 我能否确定从文件中读取的 32 字节二进制数据等于 256 位?

c++ - 从 Makefile 到 Cmake

c++ - ldexp 的目的是什么?

java - 交换内容后构建新字符串的更好方法

java - 如何替换字符串中特定数量的单词?