-1

If I have the two following statements:

// OK
const int ARRAYSIZE = 5;
int x[ARRAYSIZE];

// NOT OK
int ARRAYSIZEBAD = 5;
int y[ARRAYSIZEBAD];

And I don't compile with the -pedantic-errors flag... why is the second example a bad thing? In what situation would it be preferable to use dynamic allocation with the new operator?

7
  • 7
    It's not bad per se, it's just not a feature the language offers. The size of things must be known at compile time which means you need a compile time known value for array sizes. Commented Feb 25, 2019 at 17:49
  • " In what situation would it be preferable to use dynamic allocation with the new operator?" this is maybe a completely different question. Related but not the same as the rest of your question Commented Feb 25, 2019 at 17:53
  • In addition to what NathanOliver said, if you want to dynamically create an array like in the second example, you can use int* y = new int[ARRAYSIZEBAD]; Commented Feb 25, 2019 at 17:55
  • 1
    @user463035818 yep this is a dupe of that question... Commented Feb 25, 2019 at 18:02
  • 3
    @JoeBass "because the compiler says so" is not very good answer. Better answer is "because the language says so". Commented Feb 25, 2019 at 18:11

4 Answers 4

6

C++ Why are non-const array declarations bad?

Because the length of the array must be known at the time of compilation. If a variable is non-const, then its value could change at run time, and thus would not be known at compile time. Only a compile time constant expression can be used as the length of an array - thus a const variable can only be used as the length of an array after its initialiser has been observed.

int[ARRAYSIZE] is a type. The requirement that size is known at compile time extends to all types that you instantiate, not just array types.

In what situation would it be preferable to use dynamic allocation ...

You need dynamic allocation when you don't know the length of the array at compile time.

You also need non-automatic allocation when the array is big. This is because the memory reserved for automatic allocation is often quite limited.

... with the new operator?

It's rarely preferable to allocate dynamic memory using a new-expression. std::vector is typically used when dynamic array is needed.

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

Comments

2

As a couple of people of people have pointed out, C++ usually determines array sizes at compile time, not run time.

A variable has its value set at runtime, so there is no way to determine the size at compile time. That is, except for constant variables. Constant variables have a constant value through the entire program, and, thus, can be determined at compile time.

If you need an array that has a dynamic size, you have the option of the new keyword:

int* y = new int[mySize];

Of course, when you're done with it, you should delete it as well.

delete[] y;

Edit: Thanks to @WhozCraig who reminded me/pointed out that you have an even better option than new/delete. You can also use vector as well.

To use, just include <vector>

#include <vector>

and you can use it like this:

std::vector<int> y; // replace int with any type of object you want

This will allow you to dynamically modify the size of your "array" (so to speak) any time you want.

3 Comments

delete [] y; or better still toss all of that for std::vector<int> y(mySize);
Ah. Great point. Vector is much better.
Also, thanks for pointing out the delete [] y; thing. I forgot which one was the right one.
1

The reason it's bad is that it's not valid C++ code. Some C++ compilers will compile it because of support for Variable-Length-Arrays (VLAs), but this is not a core supported C++ language feature and will not work on all Standard-conforming compilers.

In C++, if you know at compile-time the length of an array, you should use std::array<int, 5>, which is a replacement for and strictly better version of the "C-style array", i.e. int arr[5];. If you do not know the length at compile-time, and have to determine it at run-time, you should use std::vector<int>, which is a replacement for int* arr = new int[5];, and which has the added benefit that you don't need to remember to call delete[] later on, as the vector object will make sure the deleter is correctly called if the object goes out of stack.

1 Comment

"if you know at compile-time the length of an array, you should use std::array<int, 5>" -- one comment: this is only true if the length is not too large because too large arrays (on the stack) can cause stack overflow.
-5

Remember: C and C++ are not Java. Arrays, for instance, are just a pointer to N pieces of memory. They are not Objects where you could store additional information, such as the size of the array. Thus, the compiler needs to know the size.

The reason isn't obvious for vectors. After all, you can use int * instead and then allocate whatever size you want.

But if you have a multi-dimensional array, it becomes more obvious why the compiler must know the size.

int myArray[3][3];

This is still just 9 ints of memory stored in the order of [0][0], [0][1], [0][2], [1][0] etc. So to get to myArray[2][1], the compiler knows to go to the 8th integer.

But here's a little more info on why it matters for 1-D arrays.

int myArray[10];
int myNextArray[5];

In this case, you have two pieces of memory, one that's 10 ints long and one that's 5 ints long. If the compiler doesn't know the size of them, how will it know how much space they each take, so it knows how to set up at the start of your method?

Or imagine this.

int size = 10;
int myArray[size];

size = 20;

How big is the array?

If you need dynamic arrays, use dynamic arrays.

9 Comments

" Arrays, for instance, are just a pointer to N pieces of memory" - no, they are not. Arrays are not pointers.
"If you need dynamic arrays, use dynamic arrays." - In the form of std::vector.
Neil Butterworth, when you pass an array of integers, what are you passing? What word would you prefer I had used instead? Handle? That sounds very OO to me. If you can come up with a better way of putting it, feel free, and i can edit my response.
@JosephLarson you could be passing the array (by reference), a pointer to array or a pointer to the first element of the array.
The difference between an array itself and the pointer it decays to is pretty important in the context of this particular question, which is about arrays themselves and not about using pointers to them.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.