4

在使用 Java 一段时间后,我决定回到 C++,现在我对字符串在 C++ 中的工作方式感到非常困惑。

首先,假设我们有一个函数:

void fun() {
   int a = 1;
   Point b(1,2);
   char c[] = "c-string";
}

据我了解,ab分配在堆栈上。c(指针)也在堆栈上分配,但内容(“c-string”)在堆上愉快地生活。

Q1:函数结束c时会自动释放内容吗?fun

其次,假设我们有一个 c++ string

void fun2() {
  (1) string s = "c++ string";
  (2) s += "append";
  (3) s = "new contents";
  (4) s = "a" + s + "c";
}

字符串文档对字符串的工作方式并不太具体,所以这里有一些问题:

Q2:结束后的内容会s自动释放fun2吗?

Q3:当我们连接两个字符串时会发生什么?我应该关心内存使用情况吗?(第 2 行)

Q4:当我们覆盖字符串的内容(第 3 行)时会发生什么 - 内存呢,我应该担心吗?最初分配的空间是否被重复使用?

Q5:如果我构造一个这样的字符串会怎样(第 4 行)。这个很贵吗?字符串文字 ( "a", "c") 是池化的(就像在 Java 中一样)还是在整个最终可执行文件中重复?

我最终要学习的是如何在 C++ 中正确使用字符串。

感谢您阅读本文,
魁魁格

4

4 回答 4

8

据我了解, a 和 b 是在堆栈上分配的。c(指针)也在堆栈上分配,但内容(“c-string”)在堆上愉快地存在。

这是错误的,它们都存在于自动内存(堆栈)中。连char阵。在 C++ 中,字符串是类型的对象std::string

Q1:函数fun结束时c的内容会自动释放吗?

是的。

Q2:fun2结束后s的内容会自动释放吗?

是的。

Q3:当我们连接两个字符串时会发生什么?我应该关心内存使用情况吗?(第 2 行)

它们是连接在一起的,并且内存是自动管理的。(假设我们在谈论std::string而不是char[]or char*

Q4:当我们覆盖字符串的内容(第 3 行)时会发生什么 - 内存呢,我应该担心吗?最初分配的空间是否被重复使用?

实施细节。它可以重复使用,如果以前的内存不能容纳新的内容,它可以重新分配。

Q5:如果我构造一个这样的字符串会怎样(第 4 行)。这个很贵吗?字符串文字(“a”,“c”)是池化的(就像在 Java 中一样)还是在整个最终可执行文件中重复?

可以合并字符串文字,但这不是必需的。对于大型连接,通常使用 astd::stringstream代替(类似于 Java)。但是首先要配置文件,不要过早进行优化。并不是说这些都不是字符串文字。

char* pStr = "this is a string literal";

它驻留在只读内存中,无法修改。

我最终要学习的是如何在 C++ 中正确使用字符串。

使用std::string.

于 2012-09-04T06:26:32.760 回答
8

c不是指针。它是一个数组。你可以说它是一个数组,因为它有方括号,而指针有一个星号。由于c是一个自动变量,它不需要任何手动生命周期或内存管理。

广告Q2:s也是一个自动变量,因为它是一个精心设计的类类型,这意味着你不需要手动处理任何事情。

广告 Q3:本地字符串对象被适当修改以包含新字符串;在此过程中,在连接表达式期间可能存在也可能不存在临时字符串对象。(这仅适用于第 4 行;第 2 行没有临时性。)

广告 Q4:一切正常,按预期工作;见第二季度。原始内存可能会被使用,也可能不会被使用,这取决于分配的细节。在您的示例中,原始内存可能会被覆盖;在类似的情况下s = std::string("hello");,两个字符串的缓冲区可能会被交换。

广告 Q5:字符串字面量是只读的全局常量,编译器可以按照自己喜欢的方式实现。细节不是那么重要;你肯定会strings. 请参阅第三季度关于临时对象。

要“学习如何在 C++ 中使用字符串”,只需去使用它们。将它们视为整数。它会是正确的。标准库的美妙之处在于你真的不需要知道“事情是如何工作的”;当您以惯用的 C++ 方式使用标准库类时,所有资源管理都会自动且高效地为您完成。

于 2012-09-04T06:29:29.530 回答
1

Q1:是的,它已被取消分配。字符数组驻留在函数的堆栈中。

Q2:是的,std::string负责在销毁时释放其所有资源,这发生在离开范围时,就像对所有自动分配的变量一样。

Q3:不,你不应该担心,除非分析告诉你应该担心。

Q4:您不用担心,原来的空间可能会被重复使用,也可能不会被重复使用。在任何情况下,字符串使用的所有空间都会在退出函数时释放。

Q5:考虑到优化,允许编译器做出确定 X 是否比 Y 更昂贵的唯一方法是分析它们两者。

于 2012-09-04T06:26:20.217 回答
0

Q1应该注意文字"c++ string","append","new contents","a","c"在静态内存中

于 2012-09-04T06:29:57.503 回答