C ++: Что означает «новая» коллекция, которая будет продолжать расти? - PullRequest
0 голосов
/ 16 июля 2010

Я новичок в C ++.Что это значит именно для «новой» коллекции?Например:

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

Когда вы «что-то новое», вы должны точно знать, насколько большим оно должно быть, верно?Поэтому, когда я использую конструктор присваивания для копирования объекта, как компьютер узнает, сколько памяти должно быть выделено в куче?Например:

*tmp = another_string_list;

another_string_list копируется в мой новый файл UnicodeStringList в памяти кучи, но я никогда не определял, насколько большим должен быть размер кучи.И компилятор не знает, насколько велик список other_string_list, поэтому сколько памяти уходит в кучу?

Я в замешательстве и, надеюсь, я достаточно подробно сформулировал свой вопрос, чтобы кто-то меня понял, но я не уверен.

Пожалуйста, помогите

Спасибо,

Джулиан

Ответы [ 6 ]

5 голосов
/ 16 июля 2010

Размер std::list не изменяется при добавлении к нему элементов.Я собираюсь использовать std::vector, потому что пример проще, но применяется та же концепция: std::vector содержит указатель на массив, который динамически изменяется по мере необходимости, чтобы содержать ваши элементы.Указатель на массив не изменяется по размеру (это размер одного указателя), хотя массив, на который он указывает, изменяется

3 голосов
/ 16 июля 2010

Все, что делает "new", это выделяет достаточно места для хранения всех переменных-членов для вашего std::list. Все, что может потребоваться сделать, - это дело std::list, и оно должно позаботиться об этом само (через своих конструкторов и деструкторов).

2 голосов
/ 17 июля 2010

Когда вы "новый" что-то, вы должны точно знать, насколько большим вам это нужно, верно?

Не совсем.По крайней мере, не так, как вы думаете об этом.

Когда вы 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.

1 голос
/ 16 июля 2010

Когда вы new и объект, вы получаете память, которая требуется для этого объекта в его начальном состоянии. Тем не менее, вы должны понимать, что класс может реализовать немного сложности в том, как он справляется со своим внутренним состоянием.

Специально для вашего вопроса класс (в вашем случае list<>) может сам динамически выделять и освобождать память в ходе своих операций. И именно это будет делать ваша коллекция list - когда элемент добавляется в список, он выделяет память для этого элемента и выполняет все необходимые действия для управления этим новым элементом, обычно с использованием указателей или объектов интеллектуальных указателей. Таким образом, память , используемая объектом list<>, может измениться, но сам объект списка «core» остается того же размера, что и при первоначальном выделении.

1 голос
/ 16 июля 2010

Единственное место, где вы действительно должны знать, насколько большим будет что-то, - это стек.Стек должен расти очень статично, чтобы удовлетворить ваш компилятор.Куча, однако, не имеет таких ограничений.

Когда вы new что-то, вы размещаете это в куче.Поэтому он может быть любого размера.Что вас удивляет, так это то, что коллекции могут также размещаться в стеке.Это происходит потому, что независимо от того, что содержит коллекция, ее размер остается неизменным.Скорее, он содержит информацию (например, указатели) к куче, где размер выделения должен быть вариантом.

0 голосов
/ 16 июля 2010

Возможно, вы захотите посмотреть, что нового делает.Он помещает его в кучную память вместо стековой памяти.Таким образом, он не исчезнет, ​​когда вы потеряете прицел.Это не имеет ничего общего с известным размером.Возможно, вы путаете это с массивами, когда при выделении памяти для массива вам нужно знать размер, а вы обычно его обновляете.

...