将字符串保存在集合中时,C_STR()仍然有效

Is c_str() still valid when the string is kept in a set

本文关键字:STR 有效 保存 字符串 存在 集合      更新时间:2023-10-16

我有一个旧的项目可以维护周围使用const char *的旧项目。由于某种原因,我想保留大量的运行时生成的字符串。因此,我创建了一个全局变量STD ::设置以保持这些字符串。当生成一个新字符串时,除了要添加到集合中,我还将返回并发送newstring.c_str()out,它将保存在其他地方。例如。

std::set<std::string> g_stringDB;
void ArchieveString( AStruct *container, const char *temporaryString )
{
    auto it = g_stringDB.emplace( temporaryString );
    container->validString = it->first->c_str();
}

我想知道外部何时使用容器(我的意思是在此功能之外的任何地方)。如果指针:有效弦仍然安全。Poiner是否有可能由于副本而指向其他东西,构造发生在集合中?如果没有,什么是实施此要求的理想方法?

c_str()返回无效的规则是:

将对字符串的非cont介引用到任何标准库函数,

调用在字符串上的非const成员函数,不包括操作员[],at(),front(),back(),begin(),rbegin(),end(),end()和rend()。

对于集合元素,由于迭代器没有无效,您在那里很好,字符串对象没有更改。

因此,如果字符串是固定的,则可以。

如果满足多个条件,可能是安全的。

首先,根据CPPReference std::basic_string::c_str()

从C_STR()获得的指针可能是无效的:

  1. 将对字符串的非cont键转移到任何标准库 功能,
  2. 或在字符串上调用非const成员函数, 排除操作员[],at(),front(),back(),begin(),rbegin(),end() and Rend()。

因此,如果这些都没有发生,则用法是安全的。上述事情也可以通过分配运算符,破坏者或任何使参考std::set<std::string>元素无效的事物发生。

无效这些引用的内容是(或在非常具体的方案中无效):

  1. std::set::insert(),如cppreference中所述

    没有迭代器或参考文献无效。

    但是,关于通过节点手柄获得的元素(C 17)有一个更细颗粒的陈述,这是有道理的:

    如果插入成功,则指示和对在节点句柄中保存时获得的元素的指示将无效,并且在提取该元素之前获得的指针和引用是有效的。(由于C 17)

  2. std::set::erase来自cppReference

    参考文献和迭代器对擦除的元素无效。其他参考文献和迭代器不受影响

  3. std::set::emplacestd::set::emplace_hint say

    没有迭代器或参考文献无效。

  4. std::set::extract

    指示器和提取元素的引用仍然有效,但在元素由节点句柄所有时不能使用:如果将元素插入到容器中,则它们将变得可用。

    这意味着在重新插入后,C_STR字符串再次安全。但是,本文档对其他参考文献没有任何说法。它可能是CPPReference和/或标准中的缺陷。我想看有关标准的评论。

  5. std::set::merge

    所有指针和对转移元素的引用仍然有效

因此,只要没有任何修改set中的对象,您就应该安全。通过阅读上述列表来确保。