The only real trick is that there are two ways to declare an array:
statically
1 2 3 4
|
int main()
{
int a[12]; // here is an array that has 12 elements
|
dynamically
1 2 3 4
|
int main()
{
int* a = new int[12]; // here is a dynamically-allocated array with 12 elements
|
The first significant difference is that the first has its size built in to the program. That array of twelve elements exists when main() starts, and remains that way so long as main() exists (and possibly longer).
Whereas the second is only created at the time that
new is used, which can be any time:
1 2 3 4 5 6 7
|
int main()
{
int* a = nullptr;
// do other stuff
a = new int[12];
|
What is also nice about the dynamic array is that it's size is not fixed by the compiler. You can, for example, get a size from the user:
1 2 3 4 5 6 7 8 9 10 11
|
int main()
{
int* a = nullptr;
int n;
cout << "How many elements? ";
cin >> n;
/* in real code, please make sure that n has a valid value before continuing! */
a = new int[n]; // create an array with some user-defined number of elements
|
Another significant difference is
where the array is created. A static array appears in one of two places: in the global data segment (for global variables) or on the stack (for function-local variables). A "dynamic" array (one created "dynamically" with
new) is located on the heap.
If you don't know what any of that means, don't worry about it. You'll get into those kinds of details later.
The final significant difference is
scope. A static array is bound to the enclosing scope. So a global array exists during the entire program. An array declared in a function exists only so long as that function has not
returned.
A dynamic array is not bound to the lifetime of any function. It exists from the time you create it with
new[] to the time you destroy it with
delete[], which can be any time you like.
With all that, the compiler only knows extra stuff about your array when it is a static array declared in a using scope -- which means that the compiler can only tell you how many elements your array has:
- (1) anywhere, if it is a static global array, or
- (2) in the function it is declared, if it is a static local array
Anywhere else, you are dealing with no more information than if you had a pointer -- the same as if you created an array dynamically.
What this boils down to is that you must keep track of the size of your array yourself. But wait, there's more! Not only does your array have a size, but often, you also want to keep track of how many elements are actually
used in your array!
So at this point we want the following pieces of information:
1 2 3
|
int* address_of_the_array;
int size_of_the_array; // also called the 'capacity'
int elements_used_in_the_array;
|
One might think it useful just to have a struct (or class) to keep all this information together. And so it was with the STL: the
std::vector, which does this for us.
Hope this helps. :O)