Reputation: 5070
What are the differences between the following notations?
int * arrayA = new int[5];
int arrayB[5];
I am aware that the first line would return a pointer type whereas the second line returns an int[]
type — but what happens inside? How would I programmatically determine the element count of arrayA
?
Upvotes: 1
Views: 107
Reputation: 254461
What are the differences between the following notations?
The first allocates a dynamic array and gives you a pointer to it. You will need to delete the array (delete [] p
) when you no longer need it, otherwise the memory will leak. It's usually best not to use raw pointers to manage dynamic resources, as it's tricky to make sure it's correctly deleted. Prefer RAII classes such as std::vector<int>
to manage the resource automatically.
The second declares an array in whatever scope the declaration appears in. If this is inside a function, it has automatic storage duration and will be destroyed automatically when it goes out of scope. If it's outside a function, it has static storage duration and will be destroyed automatically at the end of the program.
How would I programmatically determine the element count of arrayB?
In the C manner:
size_t arrayB_size = sizeof arrayB / sizeof arrayB[0];
or in the C++ manner:
template <typename T, size_t N> size_t array_size(T(&)[N]) {return N;}
size_t arrayB_size = array_size(arrayB);
Note that you can't determine the size of the dynamic array - that information is lost. The first style would give a bogus result (based on the size of a pointer rather than the array), and the second would fail to compile. That's another reason to perfer vector
, which knows its size.
Upvotes: 3
Reputation: 310980
I think you mean
int arrayB[5];
instead of
int [5] arrayB;
because the last one is not a legal C++ declaration. Such a declaration is used in C#.
In this case
int * arrayA = new int[5];
an unnamed array is created in the heap and the address of the first element of the array is assigned to pointer arrayA. Variable arrayA knows nothing about how many elements you allocated. For example these two variables below have the same type
int *array1 = new int[5];
int *array2 = new int[10];
In the second case
int arrayB[5];
variable arrayB denotes an array of 5 elements of type int. it has type int[5] and knows that it has 5 elements. For example int[5] and int[10] are two different types.
Upvotes: 3
Reputation: 153919
The first allocates the memory dynamically. The lifetime of the
array lasts until you explicitly free it (delete [] arrayA;
).
In practice, there is never any reason to do this; just use
std::vector<int>
(so you don't have to worry about the
delete).
The second creates an array as a local variable. It will cease
to exist when the variable goes out of scope. If for some
reason you cannot use std::vector
, then prefer this solution.
With regards to the size of the array: in the first case, it's
up to you to manage it. As far as the language is concerned,
all you have is a pointer. In the second case, you can get the
size using the standard functions std::end( arrayA
) - std::begin( arrayA )
(at least in C++11). Or if you're
passing it to another function, you can pass it by reference; if
the other function is a template (e.g. template <size_t N> void
func( int (&array)[N] )
), the compiler will instantiate it with
the correct size. If it isn't a template (e.g. void func( int
(&array)[5] )
), the compiler will complain if the size is not
correct.
Upvotes: 3
Reputation: 171127
The difference is that arrayB
is an array with automatic storage duration (~ on the stack if it's a local variable), while arrayA
is a pointer to the first element of an array with dynamic storage duration (~ on the heap).
The element count of arrayB
can be determined like this:
template <class T, size_t N>
size_t getElementCount(T (&)[N]) { return N; }
int main() {
assert(getElementCount(arrayB) == 5);
}
The element count of arrayA
can not be determined. It's not stored in any place accessible to your program.
Upvotes: 4