You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何长度小于16字节的std::string不触发重载new?内存分配位置在哪?

关于std::string短字符串内存分配的问题

基础追踪代码

我们通过重载new运算符来追踪std::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);
}

示例1:长字符串初始化

当使用较长字符串初始化std::string时:

int main()
{
    std::string name = "Hello World 1234";
    std::cout<<"No. of allocations="<<s_AllocCount<<std::endl;
    return 0;
}

输出

Allocating 17 bytes
No. of allocations=1

示例2:短字符串初始化

当使用较短字符串初始化std::string时:

int main()
{
    std::string name = "Hello World";
    std::cout<<"No. of allocations="<<s_AllocCount<<std::endl;
    return 0;
}

输出

No. of allocations=0

问题

为何在示例2中,长度小于16字节的std::string未调用重载的new运算符?该字符串的内存初始化发生在何处?

解答

这是因为标准库的std::string实现普遍采用了**短字符串优化(SSO,Short String Optimization)**机制:

  • 当字符串的长度小于某个阈值(多数实现中是15字节,加上结束符共16字节)时,字符串的内容会直接存储在std::string对象本身的内部缓冲区中,不需要向堆内存申请空间。
  • 只有当字符串长度超过这个内部缓冲区的容量时,std::string才会通过new运算符在堆上分配内存来存储字符串内容,此时才会触发我们重载的operator new。

简单来说,示例2中的短字符串直接存在std::string对象自身的内存里,完全不需要堆分配,所以不会调用new,自然不会被我们的追踪代码统计到。

内容的提问来源于stack exchange,提问作者Santosh Sahu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 10:02:32