C++: What does it mean to "new" a collection that will keep growing?
I am new to C++. What does it mean exactly to "new" a colle开发者_运维问答ction? For example:
UnicodeStringList* tmp = new UnicodeStringList;
// where UnicodeStringList is typedef to std::list<UnicodeString>
When you "new" something you have to know exactly how big you need it to be, right? So when I use the assignment constructor to copy an object, how will the computer know how much memory should be allocated on the heap? For example:
*tmp = another_string_list;
another_string_list is being copied into my new'd UnicodeStringList in heap memory, but I never initially specified how big that heap memory ought to be. And the compiler doesn't know how big another_string_list is so how much memory goes into the heap?
I am confused and hopefully I've specified my question enough so someone may understand me, but I'm not sure.
Please help
Thanks,
Julian
The size of a std::list
doesn't change when you add elements to it. I'm going to use a std::vector
because the example is simpler, but the same concept applies: a std::vector
contains a pointer to an array, which is dynamically resized as needed to contain your elements. The pointer to the array doesn't change in size (it's the size of one pointer), even though the array it points to changes
All that "new" does is allocate enough space to store all the member variables for your std::list
. Anything extra that may need to be done is the std::list
's business, and it should take care of that itself (via its constructors and destructors).
When you "new" something you have to know exactly how big you need it to be, right?
Not exactly. At least, not in the way that you're thinking about it.
When you new
a raw array then of course you have to provide the number of elements in the array. But std::list
, std::vector
, and such are not raw arrays.
Taking std::list
as an example: From the outside, you can think of it as something that contains whatever you put into it. However, in detail, it is an object that directly contains only pointers. Those pointers point to other objects that it has allocated on the heap (using new
). Thus an instance of std::list
itself is always the same size, however as you add more things to it, it will end up allocating more stuff elsewhere on the heap to manage it.
This is also why you can use a list as a stack-allocated local variable and not have trouble pushing any number of items into it.
UnicodeStringList MyList;
MyList.push_back(item1);
MyList.push_back(item2);
No need for new
. The list arranges its own internal (heap allocated) bookkeeping to accommodate as my items and you want to add to it.
And so when one list A assigned to list B. All items (and any internally managed bookkeeping objects) from list A are copied into newly heap allocated items and given to list B to manage.
The only place where you actually have to know how big something will be is on the stack. The stack must grow in a very statical way to please your compiler. The heap, however, has no such constraints.
When you new
something, you allocate it on the heap. Therefore, it can be of any size. What surprises you should rather be that collections can also be allocated on the stack. This is because no matter what a collection contains, its size is invariant. Rather, it contains informations (like pointers) to the heap where the size of an allocation must be variant.
When you new
and object, you get the memory that is required for that object in it's initial state. However, you need to realize that a class can implement quite a bit of complexity in how it deals with its internal state.
Specifically for your question, a class (in your case a list<>
) can itself dynamically allocate and release memory during the course of it operations. And that's what your list
collection will do - when an item is added to the list, it'll allocate memory for that item and perform whatever housekeeping is necessary to manage that new item, usually using pointers or smart pointer objects. So the memory used by the list<>
object may change, but the 'core' list object itself remains the same size as when it was allocated originally.
You might want to look up what new does. It puts it on the heap memory instead of stack memory. This way, it's not going to go away when you lose scope. It has nothing to do with the known size. You might be confusing this with arrays, where when you allocate the memory for an array you need to know the size, and you typically new it.
精彩评论