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

循环内std::string内容存储地址为何相同?代码如何修正?

问题分析与解决方案

一、原始代码的问题

循环内定义的std::string s是栈上的局部变量,每次循环迭代结束时,s会被销毁,其底层存储的内存会被系统回收。c_str()返回的是指向该底层内存的指针,此时指针成为悬空指针,后续访问属于未定义行为(输出内容随机或崩溃都有可能)。

你观察到所有指针地址相同,是因为栈帧被重复利用:每次循环创建s时,操作系统分配的栈内存位置完全一致,所以c_str()返回的地址重复。

二、修改后代码的问题

你新增std::vector<std::string> str_vec存储字符串的思路是对的,但忽略了std::vector的扩容机制:当str_vec的当前容量不足以容纳新元素时,它会重新分配一块更大的内存空间,将原有元素拷贝/移动到新内存,然后释放旧内存。此时之前通过str_vec.back().c_str()获取的指针,指向的是已经被释放的旧内存,同样变成悬空指针,访问结果自然不符合预期。

三、正确解决方案

方案1:预分配vector容量避免扩容

通过reserve()提前为str_vec分配足够的内存,避免后续push_back触发扩容,确保每个std::string的底层存储地址不会变化:

int main()
{
    std::vector<char*> char_vec;
    std::vector<std::string> str_vec;
    // 预分配能容纳10个元素的内存,避免扩容
    str_vec.reserve(10);

    for(size_t i = 0; i < 10; i++)
    {
        str_vec.push_back("test" + std::to_string(i));
        char_vec.push_back(const_cast<char*>(str_vec.back().c_str()));
    }

    for(auto& ele : char_vec)
    {
        std::cout << ele << std::endl;
    }
}

方案2:直接存储std::string(最推荐)

如果你的场景不需要直接使用char*,建议直接用std::vector<std::string>存储,完全规避指针问题,同时保留std::string自动内存管理的优势:

int main()
{
    std::vector<std::string> str_vec;
    for(size_t i = 0; i < 10; i++)
    {
        str_vec.push_back("test" + std::to_string(i));
    }

    for(auto& ele : str_vec)
    {
        std::cout << ele << std::endl;
    }
}

方案3:必须使用char*时的堆内存拷贝(不推荐)

如果因特殊需求必须保留char*,可以手动将std::string的内容拷贝到堆内存(注意:此写法需要手动释放内存,失去了std::string简化内存管理的意义):

int main()
{
    std::vector<char*> char_vec;
    for(size_t i = 0; i < 10; i++)
    {
        std::string s = "test" + std::to_string(i);
        // 分配堆内存并拷贝字符串内容
        char* ptr = new char[s.size() + 1];
        strcpy(ptr, s.c_str());
        char_vec.push_back(ptr);
    }

    for(auto& ele : char_vec)
    {
        std::cout << ele << std::endl;
        // 手动释放堆内存,避免泄漏
        delete[] ele;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:50:23