8

assume that we created dynamically allocated memory such as:

int SIZE = 10;
int *p = new int[SIZE];
for(int i = 0; i < SIZE; ++i)
  p[i] = i;

it will assing 0 to 9 to our pointer array.
Then i wanted to add 10,11,12 to the array
can i do :

p[10] = 10;
p[11] = 11;
p[12] = 12;

or should i do:

delete[] p;
size = 13;
p = new int[SIZE];
for(int i = 0; i < SIZE; ++i)
  p[i] = i;
19
  • 13
    Since this is C++, why don't you use a vector<int> directly? Commented Nov 18, 2019 at 14:16
  • 1
    That's nowhere near helpful. I think if the question involved using an array, that advice is good as an "also ..." side answer, but this question is very specificly about dynamic arrays. SO is earning its stereotype right now. Commented Nov 18, 2019 at 14:19
  • 1
    To resize an array you have to allocate a new array and copy the old elements to the new array, then delete the old array. stackoverflow.com/questions/42238712/change-array-size-c Commented Nov 18, 2019 at 14:19
  • 4
    @sweenish -- The comment section is for comments, not answers. I see nothing wrong with commenting on why vector is not used. Commented Nov 18, 2019 at 14:19
  • 3
    @machine_1 - Only if the memory has been allocated using malloc(), calloc(), realloc(). But usage of those functions (from C) is discouraged in C++, for various reasons - in particular, it gives undefined behaviour is used to allocate memory for C++ class types that have a non-trivial constructor or destructor. Commented Nov 18, 2019 at 14:27

3 Answers 3

7

You have to reallocate memory for the array of a greater size. Otherwise the program will have undefined behavior.

For example

int SIZE = 10;
int *p = new int[SIZE];
for(int i = 0; i < SIZE; ++i)
  p[i] = i;

int *tmp = new int[SIZE + 3];

std::copy( p, p + SIZE, tmp );
delete []p;
p = tmp;

p[SIZE++] = 10;
p[SIZE++] = 11;
p[SIZE++] = 12;

Or instead of the last three statements you can write

for ( const int &value : { 10, 11, 12 } ) p[SIZE++] = value;

Of course in such cases it is better to use the standard container std::vector.

In fact the code above is similar to the following

#include <vector>

//...

std::vector<int> v( 10 );

for ( int i = 0; i < v.size(); i++ ) v[i] = i;

v.reserve( 13 );
for ( const int &value : { 10, 11, 12 } ) v.push_back( value );

except that all the memory management is done internally by the vector.

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

4 Comments

Is it wrong to shake in disgust when looking at p[SIZE++]?
As we are deleting the old array anyway, I'd prefer std::move over std::copy – while irrelevant for integers, it might make quite a difference for complex types (like std::string)...
@Aconcagua I agree with you.
Hm, not necessarily equivalent, the constructor might decide to reserve more elements right from the start, in which case re-allocation might not occur. And std::vector would move, if possible...
3

The second option is the correct way. The first option won't always complain, but you are writing to memory that has not been set aside for your array; it has been set aside for something else, and you don't know what. Sometimes it will behave okay, sometimes it won't. Assigning to an array outside its range is Undefined Behavior, and we should avoid it.

2 Comments

Second option is wrong since it mixes size and SIZE.
I'm chalking that up to a simple typo, but it's good to bring up.
3

In your first example suggestion:

p[10] = 10;
p[11] = 11;
p[12] = 12;

You will be overwriting memory that you don't own, which can lead to a crash. You need to reallocate your original array.

const int oldSize = SIZE;
SIZE = 13;
int *newP = new int[SIZE];
memcpy(newP, p, oldSize * sizeof(int));
for (int i = oldSize; i < SIZE; ++i)
{
    newP[i] = i;
}

delete[] p;
p = newP;

Your second example would work, but is slightly less efficient, because you're re-calculating the values with each reallocation. In my example above, you only re-calculate the new values.

Alternatively, you should look at std::vector which is designed specifically for this purpose (a dynamically sizing array).

std::vector<int> p;
for (int i = 0; i < 10; ++i)
{
    p.push_back(i);
}

Here the std::vector manages the allocation internally, so you don't have to worry about new and delete.

2 Comments

Side note: memcpy usually is invalid if complex objects are involved (like std::string). For consistency, I'd then avoid memcpy even for types where it actually is allowed in favour of the C++ means like std::copy.
Yep I agree, the original intention of my answer was to preserve the "style" of the question (i.e. raw pointers and manual memory management), but yes, the memcpy should be discouraged.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.