0

我是 C++ 新手。“新”系列究竟意味着什么?例如:

UnicodeStringList* tmp = new UnicodeStringList;
// where UnicodeStringList is typedef to std::list<UnicodeString>

当你“新”一些东西时,你必须确切地知道你需要它有多大,对吧?那么当我使用赋值构造函数复制一个对象时,计算机如何知道应该在堆上分配多少内存呢?例如:

*tmp = another_string_list;

another_string_list 正在被复制到堆内存中我新的 UnicodeStringList 中,但我最初从未指定该堆内存应该有多大。而且编译器不知道 another_string_list 有多大,所以有多少内存进入堆?

我很困惑,希望我已经足够详细地说明我的问题,以便有人可以理解我,但我不确定。

请帮忙

谢谢,

朱利安

4

6 回答 6

6

向其中添加元素时,a 的大小std::list不会改变。我将使用 astd::vector因为示例更简单,但同样的概念也适用:astd::vector包含一个指向数组的指针,该数组会根据需要动态调整大小以包含您的元素。指向数组的指针的大小不会改变(它是一个指针的大小),即使它指向的数组发生了变化

于 2010-07-16T17:56:39.063 回答
3

“新”所做的只是分配足够的空间来存储您的所有成员变量std::list。任何可能需要做的额外事情都是std::list's 的事情,它应该自己处理(通过它的构造函数和析构函数)。

于 2010-07-16T18:01:58.917 回答
2

当你“新”一些东西时,你必须确切地知道你需要它有多大,对吧?

不完全是。至少,不是你想的那样。

当你new是一个原始数组时,当然你必须提供数组中元素的数量。但是std::list, std::vector, 等不是原始数组。

std::list个例子:从外面看,你可以把它想象成一个东西,里面装着你放进去的任何东西。但是,详细地说,它是一个直接只包含指针的对象。这些指针指向它在堆上分配的其他对象(使用new)。因此,一个自身的实例std::list总是相同的大小,但是当你向它添加更多东西时,它最终会在堆的其他地方分配更多的东西来管理它。

这也是为什么您可以将列表用作堆栈分配的局部变量并且不会遇到将任意数量的项目推入其中的原因。

UnicodeStringList MyList;
MyList.push_back(item1);
MyList.push_back(item2);

不需要new。该列表安排了自己的内部(堆分配)簿记,以容纳我的项目,并且您想要添加到它。

因此,当一个列表 A 分配给列表 B 时。列表 A 中的所有项目(以及任何内部管理的簿记对象)都被复制到新堆分配的项目中,并交给列表 B 进行管理。

于 2010-07-16T21:05:10.730 回答
1

当您new反对时,您将获得该对象在其初始状态所需的内存。但是,您需要意识到一个类在处理其内部状态的方式上可以实现相当多的复杂性。

特别针对您的问题,一个类(在您的情况下为 a list<>)本身可以在它的操作过程中动态分配和释放内存。这就是你的list集合要做的——当一个项目被添加到列表中时,它将为该项目分配内存并执行管理该新项目所需的任何内务管理,通常使用指针或智能指针对象。因此对象使用的内存list<>可能会改变,但“核心”列表对象本身的大小与最初分配时的大小相同。

于 2010-07-16T19:15:13.593 回答
1

唯一真正需要知道某物有多大的地方是堆栈。堆栈必须以非常静态的方式增长才能取悦您的编译器。然而,堆没有这样的限制。

当你有new东西时,你在堆上分配它。因此,它可以是任何大小。更令您惊讶的是集合可以在堆栈上分配。这是因为无论集合包含什么,它的大小都是不变的。相反,它包含指向分配大小必须可变的堆的信息(如指针)。

于 2010-07-16T17:57:58.350 回答
0

您可能想查看 new 的功能。它将它放在堆内存而不是堆栈内存上。这样,当您失去范围时,它就不会消失。它与已知大小无关。您可能会将其与数组混淆,当您为数组分配内存时,您需要知道其大小,并且通常是新的。

于 2010-07-16T17:56:02.450 回答