1

I'm trying to figure out how does a vector adds more objects after it has already "Created" some:

int *ptr;
ptr = new int;

How after using that, can you add more objects to that pointer? (make it an array). Thanks!

3
  • 1
    possible duplicate of Add new objects after using "new" Commented Jan 18, 2011 at 18:24
  • The answer to this question is basically answered by your last question (which is very similar to this one). Commented Jan 18, 2011 at 18:24
  • Does this answer your question? Add new objects after using "new" Commented Aug 6, 2021 at 13:05

6 Answers 6

7

Most implementations start off with a small array, and whenever it reaches its capacity, a new array of double the size is allocated and the old elements are copied to the new array.

Sign up to request clarification or add additional context in comments.

5 Comments

True, which means it's not safe to keep pointers to objects stored in vectors, unless you take some precautions (reserve()).
@Kos I know what you mean, but I think you should reword that to make it less ambiguous. It sounds like you are saying not to store pointers in a vector.
More generally, the vector is resized to size kN for an N sized vector with constant k > 1 in order to reduce the amortized complexity of insertion to constant time.
For further comprehension, the standard essentially guarantees that std::vector contains a contiguous block of memory. (unofficial)
Most or all (I have no way of knowing it) implementations create an empty vector by default, not a small one. Because it's not that unusual that a vector will not live to see any elements stuffed into it, either because it was swapped, or moved and immediately destroyed. Also most or all implementations don't double the size, the optimal growth factor is around 1.5.
4

As with most STL containers it uses an external allocator to actually allocate the memory. This is the second template parameter to vector.

It uses placement-new to create the objects into the memory.

For adding more objects when it has run out of memory it must allocate a bigger amount. If the underlying type is POD it can just realloc, but if not it must move them with the object's operator=.

3 Comments

Does it actually use realloc()?. So malloc() is not obsolete in c++, and new is unavoidable only when the object to allocate is not POD. Can you point me to a good document where they explain why there is no renew operator in c++?
It could use realloc(). The allocator has rules as to what it needs to do, not how it does it. The only purpose I can see to renew[] would be to resize (and move if necessary) something previously allocated with new[]. However as we have vector I cannot see a need for it. realloc() with a non-POD type would be undefined behaviour as you cannot simply memmove it.
Yes I know that std::vector removes the need completely but I was just curious, thank you for your response.
3

You can't make it an array, you can only point it to one.

So when you do this:

int *ptr;
ptr = new int;

you have pointed pointer ptr to newly created integer. You can delete it and create array, and point ptr to that array:

delete ptr;
ptr = new int[5];

Comments

1
1. Build an array.
2. copy *ptr into it.
3. swap ptrs.
4. delete the temp.

There you go, you now have "resized" your ptr.

1 Comment

Now I understand it all, Thank you very much everybody!
1

A vector keeps track of two bits of information.

  1. It's size, which is the number of elements it's currently holding.
  2. It's capacity, or how many elements it can actually contain before running out of memory.

If adding an element does not cause it to exceed its capacity, then there is no problem. It simply adds the new element.

If the capacity will be exceeded, then it will calculate a new capacity (usually between 1.5 and 2 times the current capacity) and copy all elements to the new array. This is why iterators are invalidated after adding an item to a vector. They may be referring to the old (now freed) array.

Comments

0

Vector can resize because it a class. It hides data inside an object and you cannot see its internal structure directly. You just work with its public interface. It can allocate a new larger array a copy data to it without you seeing it.

You cannot do this with int*, because you have no class here, no place to hide real implementation from user.

3 Comments

You could do it yourself manually with a int* arr = new int[n];, but it'd be a pain to track logical size vs. allocated size yourself.
@Toolbox: If you do this, your original data from arr[0] gets lost.
@Al Kepp: Why so? Anything you can do with a class, you can do without, but as @Toolbox put it, it's just difficult to keep track of all the variables.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.