C++ 中的连接原理是什么std::string
?它在内存分配中如何工作?
我在探索 leetcode 卡片时发现,在 Java 中:
“连接的工作方式是首先为新字符串分配足够的空间,从旧字符串复制内容并附加到新字符串”。
与 Java 不同,“在 C++ 中,这不会对性能产生明显影响”。
我认为在 C++ 中也是一样,因为动态数组的工作方式。我记得如果你想增加动态数组的容量,程序首先创建一个新的空间,其大小等于所需的大小,然后将旧数组的所有元素复制到新数组中。
C++ 中的连接原理是什么std::string
?它在内存分配中如何工作?
我在探索 leetcode 卡片时发现,在 Java 中:
“连接的工作方式是首先为新字符串分配足够的空间,从旧字符串复制内容并附加到新字符串”。
与 Java 不同,“在 C++ 中,这不会对性能产生明显影响”。
我认为在 C++ 中也是一样,因为动态数组的工作方式。我记得如果你想增加动态数组的容量,程序首先创建一个新的空间,其大小等于所需的大小,然后将旧数组的所有元素复制到新数组中。
C++ 中有两个运算符可用于
std::string
连接:二元运算符
std::string result = a + b
编译为:赋值运算符
a += b
编译为:这两种情况都可能导致内存分配,除非结果字符串恰好已经分配了足够的空间。这可能是由于先前的分配(例如通过
reserve()
调用),或者是由于小字符串优化,将最多约 15 个字节的字符串直接存储在堆栈上的结构中。Java 和 C++ 之间的显著差异是
+=
运算符(或.append()
)调用,它会就地修改字符串。Java 字符串是不可变的,因此在 Java 中不可用。修改现有字符串时,C++ 通常会分配比当前需要更多的空间,以便每次调用不会导致新的内存分配。然后不需要复制字符串的现有部分,只需复制附加部分。如果您有大量字符串或字符串很长,那么“C++ 不会对性能产生明显影响”的说法是不正确的。与 Java 不同
StringBuilder
,C++ 具有速度优势,但 C++没有直接等效的。.reserve()
提前调用将提供大致相同的性能。为了获得最佳性能,您可以重新组织代码以完全避免附加所需的复制,例如使用rope 数据结构。原则上,
std::string
C++ 中的连接与 Java 中的连接类似:您需要有足够的可用空间,然后将要连接的两个字符串的内容复制到其中。
然而 - 虽然标准没有强制要求,但大多数(如果不是全部)标准库实现都
std::string
包含一种称为小字符串优化的机制。如果字符串足够小,它可以通过直接在对象中嵌入一个小的字符数组来避免动态分配字符串内容std::string
。请注意,“足够”取决于实现。
这意味着如果你连接 2 个足够小的字符串 sch 因为结果仍然足够小 - 就不会进行动态分配。
但您仍然需要将两个字符串的内容复制到结果中。