Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is new int[n] valid when int array[n] is not?

Tags:

c++

arrays

For the following code:

foo(int n){
    int array[n];
}

I understand that this is invalid syntax and that it is invalid because the c++ standard requires array size to be set at compile time (although some compilers support the following syntax).

However I also understand the the following is valid syntax:

bar(int n){
    int *array = new int[n];
}

I don't understand why this is allowed, isn't it the same as creating an array where the size is determined at runtime? Is it good practice to do this or should I be using a vector if I need to do this instead?

like image 735
Francis Avatar asked Dec 16 '14 00:12

Francis


People also ask

Why do we use new int in Java?

new int[] means initialize an array object named arr and has a given number of elements,you can choose any number you want,but it will be of the type declared yet.

What is the use of new int?

The purpose of new is to simply reserve memory for storing an int variable on the heap instead of the traditional stack. The main advantage of using heap is that you can store a large number of int variables like in an array of 100000 elements easily on the heap.

What is new int *[ N?

int *array = new int[n]; It declares a pointer to a dynamic array of type int and size n . A little more detailed answer: new allocates memory of size equal to sizeof(int) * n bytes and return the memory which is stored by the variable array .

What does New int mean in C++?

*new int means "allocate memory for an int , resulting in a pointer to that memory, then dereference the pointer, yielding the (uninitialized) int itself".


3 Answers

That's because the former is allocated on the stack and the latter on the heap.

When you allocate something on the stack, knowing the size of the object is essential for correctly building it. C99 allows the size to be specified at run time, and this introduces some complications in building and dismantling the aforementioned stack, since you cannot calculate its size at compile time. Machine code must be emitted in order to perform said calculation during the execution of the program. This is probably the main reason why this feature wasn't included in the C++ standard.²

On the contrary, the heap has no fixed structure, as the name implies. Blocks of any size can be allocated with no particular order, as long as they do not overlap and you have enough (virtual) memory¹. In this case, knowing the size at compile time is not that relevant.

Also, remember that the stack has a limited size, mostly to detect infinite recursions before they consume all the available memory. Usually the limit is fixed around 1MB, and you rarely reach that. Unless you allocate large objects, which should be placed in the heap.

As of what you should use, probably a std::vector<int>. But it really depends on what you are trying to do.

Also note that C++11 has a std::array class, whose size must be known at compile time. C++14 should have introduced std::dynarray, but it was postponed because there is still much work to do concerning compile-time unknown size stack allocation.


¹ blocks are usually allocated sequentially for performance reasons, but that's not required.

² as pointed out, knowing the size at compile time is not a hard requirement, but it makes things simpler.

like image 87
Stefano Sanfilippo Avatar answered Oct 22 '22 09:10

Stefano Sanfilippo


In the first case you are allocating the memory space statically to hold the integers. This is done when the program is compiled and so the amount of storage is inflexible.

In the latter case you are dynamically allocating a memory space to hold the integers. This is done when the program is run, and so the amount of storage required can be flexible.

The second call is actually a function that talks to the operating system to go and find a place in memory to use. That same process does not happen in the first case.

like image 40
fbrereto Avatar answered Oct 22 '22 09:10

fbrereto


int array[n] allocates a fixed-length array on the call stack at compile-time, and thus n needs to be known at compile-time (unless a compiler-specific extension is used to allow the allocation at runtime, but the array is still on the stack).

int *array = new int[n] allocates a dynamic-length array on the heap at run-time, so n does not need to be known at compile-time.

like image 5
Remy Lebeau Avatar answered Oct 22 '22 09:10

Remy Lebeau