1

I have the following dynamically allocated array

int capacity = 0;
int *myarr = new int [capacity];

What happens if I do something like this:

for (int i = 0; i < 5; ++i) 
myarr[++capacity] = 1;

Can this cause an error if the for loop is executed many times more than 5? It worked fine for small numbers, but I'm wondering If this is maybe a wrong approach.

9
  • 6
    welcome to the land of Undefined Behaviour Commented Apr 27, 2015 at 21:00
  • 1
    This would cause an error anyway. You have created an array of size 0, anything you put in the array is actually being put after the array. Commented Apr 27, 2015 at 21:01
  • 3
    "It worked fine" - no it didn't, it just looked that way. Commented Apr 27, 2015 at 21:02
  • 4
    It is definitely the wrong approach for all possible situations. Commented Apr 27, 2015 at 21:02
  • 2
    The fact you see an error, means that you have made an error. The fact that you don't see an error, doesn't mean that you have not made an error. You are invoking Undefined Behaviour and you know it (you are writing on a memory area that you didn't allocate): what is the purpose? Commented Apr 27, 2015 at 21:03

3 Answers 3

4

You are setting memory outside of the bounds of the array. This might overwrite memory being used in another part of the program, it is undefined behavior. To fix this you should declare your array like this:

int* myArray = new int[5];

which will make it so you don't allocate out of the bounds of the array.

However, it is better to use std::vector. It will prevent situations like this from occurring by managing memory itself. You can add items to a std::vector like this:

Vector.push_back(myItem);

and you can declare a vector of ints like this:

std::vector<int> Vector;

You can read more about std::vector here.

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

Comments

2

It will cause out of bounds access. This is just undefined behaviour. Your program may crash, your car may not start in the morning, you see the pattern here.

It happens to work fine in your case because usually the OS allocates more than you ask it for, usually in multiples of 2, so probably here it allocates like 8/16..256 bytes at least. But you should not rely on this kind of behaviour.

EDIT The car issue was (almost) a joke, however undefined behaviour really means undefined. C++ standard decided to not enforce compiler checking of many of such issues, because checking takes time. So it declares the behaviour as Undefined Behaviour (UB). In this case, absolutely nothing is guaranteed. If you work e.g. on some small embedded system that controls the rudder of a plane, well, you can guess what may happen.

Comments

1

This approach is wrong in c++. Allocating memory with new allocates memory for new "capacity" objects that you can access without running in run-time error. Here is a better way to manage the raw array in c++:

int capacity = 10;
int *myarr = new int [capacity];

for (int i = 0; i < 20 ; ++i) {
  if (capacity < i) {
    // allocate more memory and copy the old data
    int *old_data = myarr;
    myarr = new int [capacity * 2]
    for (int j = 0; j < capacity; ++j) {
      myarr[j] = old_data[j];
      capacity *= 2;
    }
    delete [] old_data;
  }
  myarr[i] = 1;
}

And its always better to call delete []at the end. Another way to use pre-made dynamic array in c++ is to use the std:array(supported in c++11) or std::vector(or legacy support and the preferred option as of me) library which automatically reallocates more memory. More for the vector and array and examples here for vector here and here for std::array.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.