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

为何该C++ vector在noUrls=300,000,000时抛出bad allocation异常?

为何传入参数noUrls=300,000,000时函数会抛出bad allocation异常?

问题代码

#include <string>
#include <vector>
#include <algorithm>

void generateUrls(int noUrls)
{
    std::vector<std::string> urls;
    urls.resize(noUrls); // 这一步总能成功
    std::size_t i = 0;
    std::string url = "abcdefghijklmnop";
    
    urls[i] = "https://www." + url + ".com/home/index";
    i++;

    while (std::next_permutation(url.begin(), url.end()) && (i < noUrls))
    {
        urls[i] = "https://www." + url + ".com/home/index"; // 异常抛出点
        i++;
    }
}

int main()
{
    generateUrls(100000000);
    // 后续处理结果
    return 0;
}

已知线索

  • noUrls=300,000,000未触发int溢出,当前平台int最大值为2,147,483,647
  • 最终生成的vector预估大小约为12GB
  • 系统配置:8GB物理内存 + 16GB分页文件,预期会将部分vector存入分页文件

异常原因分析

  1. 实际内存需求远超预估
    你预估的12GB只是所有字符串的字符数据总大小,但忽略了完整的内存开销:

    • resize(300000000)会先分配存放3亿个std::string对象的内存,每个std::string对象本身(不含字符数据)通常占用24字节左右(包含指针、长度、容量字段),这部分就需要约7.2GB内存。
    • 每个赋值后的字符串长度为41字符,远超过std::string的小字符串优化(SSO)阈值(通常16~24字节),因此每个字符串都需要在堆上单独分配字符内存,这部分总大小约12.6GB。
    • 两者相加总内存需求接近20GB,再加上系统本身和其他进程占用的内存,剩余可用虚拟内存不足以覆盖这个需求。
  2. 内存碎片化导致分配失败
    3亿次小内存块(41字节左右)的分配会引发严重的堆内存碎片化。即使系统总虚拟内存剩余量理论上足够,内存管理器也可能无法找到足够的连续内存块来满足分配请求,最终触发bad_alloc异常。

  3. resize与赋值的内存阶段差异
    urls.resize(noUrls)仅初始化了3亿个空的std::string对象,空字符串利用SSO不需要堆内存,因此这一步内存占用低,能顺利完成。但后续赋值时,每个字符串都要动态分配堆内存,短时间内的大量内存申请会瞬间耗尽可用内存或触发碎片化问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 09:10:28