Declaring and Intializing Arrays in C++: Arrays
of Objects and Primitives
C++ Array Size: The Size of an Array in C++
C++ Array of Arrays: Multidimensional Arrays in C++
Multidimensional Arrays in C++ Revisited:
Dealing with Large Arrays
C++ Array Sort: Sorting Arrays in C++
Arrays are relatively straightforward in C++, but as with everything
else in C++, you don't get much fancy functionality without using add-on
libraries.
If you need anything beyond basic array functionality in C++, you can
often use functions in the
algorithm
standard library.
Beyond that you have two choices. Either link with the free
industry-standard Boost libraries (which
may
slow down your compilation or even execution to the point where you feel
like you want to tear your eyes out or emigrate to Yemen -- don't say I
didn't warn you!), or you can use
STL
(Standard Template Library)
vector
class, which should come with your compiler.
Since C++ includes no automatic runtime error checking, arrays are a
major source of memory leaks and 'access violations' or memory over-runs
in C++; this reason alone commends the use of
vector
instead of the primitive array type for many applications.
Declaring an array in C++ is very straightforward; you just give the
array a name and specify how many items it should contain in square
brackets after the name.
The following program declares two arrays.
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
// Array of five ints
int numbers[5];
// Array of four strings
string texts[4];
}
If you want to put a lot of data in your array, you'll probably want to
put your data on the heap rather than the stack, where you can manage it
yourself.
This basically means using
new
and
delete
to create and free the array, as follows. In this program, strictly
speaking we're declaring pointers, not arrays.
However, pointers and arrays behave similarly in C++ for many purposes,
and we can use the pointers declared below in pretty much the same ways
that we'd use arrays.
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
// Array of five hundred ints
int *numbers = new int[500];
// Array of four hundred strings
string *texts = new string[400];
// Free the memory
delete [] numbers;
delete [] texts;
}
If you want to declare your arrays and initialize them with data at the
same time, you can do the following.
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int numbers[] = {1, 2, 5, 10};
string texts[] = {"Apple", "Banana", "Orange"};
// Access element at index 0
cout << numbers[0] << endl;
// Access element at index 2
cout << texts[2] << endl;
}
1
Orange
In C++ there is a primitive string type and also a standard string class
(used above). The primitive string type is actually an array of 1-byte
characters, where the last character is a null character (a numerical
zero, in other words).
This program illustrates the fact.
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char text[] = "Hello there";
// Display the 'H'
cout << text[0] << endl;
// Display the null-terminator as a number
cout << (int)text[11] << endl;
}
H
0
Short answer: use
sizeof(array)/sizeof(element type)
.
For example: sizeof(scores)/sizeof(int), where scores is an array of
ints.
This does not work with pointers.
Long answer:
You can use the
sizeof
operator in C++ to find the size of a true array. However, if you've
declared a pointer and allocated an array on the heap, you can't use
sizeof
. This is a key difference between true arrays and pointers in C++; an
array knows its own size, but a pointer does not have any concept of how
much memory it's pointing to -- it only knows how big each element is.
Let's take a look. This program creates two arrays, one 'normal' array
and one array of values on the heap, referenced by a pointer. We then do
a
sizeof
on both.
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
// Create an array holding 3 fruits.
string fruit[] = {"Apple", "Orange", "Banana"};
// Create an array on the heap with new.
string *stuff = new string[3];
stuff[0] = "Apple";
stuff[1] = "Orange";
stuff[2] = "Banana";
// What does sizeof give us?
cout << sizeof(fruit) << endl;
cout << sizeof(stuff) << endl;
// Must always free memory allocated with new.
// The [] is needed because it's an array.
delete [] stuff;
}
12
4
Using
sizeof
on the true array has given us the total amount of memory the array
takes up; on other words, the size of one item (4 bytes for a string
object) multiplied by the number of items (3 in this case).
On the other hand,
sizeof
on the pointer only gives us the size
of the pointer variable itself
; even a pointer to a
char
(one byte) would still give us
4
with
sizeof
, since the pointer itself requires 4 bytes to hold a memory address.
This means that if we have a pointer to an array in C++, there is no way
to find out how many elements the pointer points to; it points to
however many you imagine it to point to, and you can point it wherever
you like -- be that at memory that you're allowed to write to, or memory
that you definitely shouldn't write to.
With a true array, we can find out its size using
sizeof(array)/sizeof(element type), as you can see in the following
example.
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
// Create an array holding 3 fruits.
string fruit[] = {"Apple", "Orange", "Banana"};
// This would not work if fruit was a pointer.
int size = sizeof(fruit)/sizeof(string);
// Loop through and print all values.
for(int i=0; i < size; i++) {
cout << fruit[i] << endl;
}
}
Apple
Orange
Banana
You can declare multidimensional arrays in C++. Let's take a look at
declaring and using a small, simple multidimensional array on the stack.
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
// Multidimensional array of numbers.
// We need to specify sizes for
// all except the first dimension.
int numbers[][3] =
{
{0, 1, 2},
{3, 4, 5}
};
for(int row=0; row < 2; row++)
{
for(int col=0; col < 3; col++)
{
cout << numbers[row][col] << endl;
}
}
}
0
1
2
3
4
5
At first it can be hard to remember which array index is which. The way
I like to think of it is this. Suppose we've got a two-dimensional array
of numbers, as above.
Since we've got an array of other arrays, numbers[i] then refers to an
array. With the first index you specify, you're saying which array you
want to use. The second index then specifies the element within that
array; numbers[i][k].
Incidentally, this is the same order that you'd use with subscript
matrix notation in mathematics; row first, then column.
You can of course create
arrays of strings
. However, take my advice and don't create arrays of primitive character
strings unless really necessary. The possibilities for memory leaks are
too great. Create arrays of standard 'string' types instead. You can
find an example further up this page.
If you have a large multidimensional array in C++, you probably don't
want to store all your data on the stack. Consider working with an array
of pointers, where each pointer is allocated with
new
and cleaned up with
delete
(or
new []
and
delete []
if you want your pointers to be pointers to arrays -- see the example
earlier on).
Often the easiest solution is to store everything in a one-dimensional
array, but then treat it as a multidimensional array conceptually.
In the following example, we work conceptually with a two dimensional
array of ints; however, the ints are actually stored linearly.
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
// Imagine we want a 2D array,
// 3 x 3 (usually you'd probably
// be working with much bigger
// numbers, or else these
// techniques would be overkill).
int width = 3;
int height = 3;
// Allocate enough memory for all
// 3 x 3 = 9 members.
// Note: we haven't caught the
// exception here; new() will
// most likely terminate your
// program at this point if there
// isn't enough memory available.
// Check your compiler's docs.
int *data = new int[width * height];
// Let's assign random values for
// each array element. Here
// we're treating the array
// as being one-dimensional.
for(int i=0; i < width * height; i++)
{
data[i] = rand();
}
// Now we'll treat the array as
// being conceptually 2D.
for(int row = 0; row < width; row++)
{
for(int col = 0; col < height; col++)
{
cout << data[row * width + col] << " ";
}
}
// Newline.
cout << endl;
// If you're worried about efficiency,
// you can do away with multiplications
// like this. Of course this only works
// if you're iterating sequentially.
int index = 0;
for(int row = 0; row < width; row++)
{
for(int col = 0; col < height; col++)
{
cout << data[index] << " ";
index++;
}
}
// Newline.
cout << endl;
// And finally, you can also do the
// same thing using pointers.
int *pData = data;
for(int row = 0; row < width; row++)
{
for(int col = 0; col < height; col++)
{
// De-reference the pointer to
// get at the data.
cout << *pData << " ";
// Move the pointer to point at
// the next item in the array.
// This works because pointers
// know what size chunks of data
// they're pointing to.
// You can't do this with a true
// array; you'd have to declare
// a pointer to the array, just
// like we've done here.
// Here, we didn't have to declare
// a new pointer (since we don't have
// a true array, just a pointer to data),
// but you might want to use a new
// pointer just so your original
// pointer carries on pointing at
// your data.
pData++;
}
}
// Newline.
cout << endl;
// Free the memory.
delete [] data;
}
16838 5758 10113 17515 31051 5627 23010 7419 16212
16838 5758 10113 17515 31051 5627 23010 7419 16212
16838 5758 10113 17515 31051 5627 23010 7419 16212
You can sort an array in C++ using the STL
sort()
function found in
The sort function takes three parameters, the third one being optional.
In fact in this case, sorting string objects in alphabetical order, we
could have omitted our custom sort function. Your custom sort function
just needs to return true if the first argument is less than the second.
But you can omit the custom sort function if your objects overload the <
operator, so that they can be compared using <.
The string class already overloads this operator, as it happens.
In the following example, you could sort in reverse alphabetical order
just by swapping a and b in the custom sort function.
You can also sort numbers using sort() of course -- then you
won't need a custom sort function unless you want them in reverse order
or something.
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
bool sort_strings(const string& a, const string& b)
{
return a < b;
}
int main(int argc, char *argv[])
{
// Declare and initialize an array of strings.
string strings[] = {
"Fox",
"Beetroot",
"Zebra",
"Aardvark",
"Cabbage"
};
// Sort the array with STL sort.
sort(strings, strings + 5, sort_strings);
for(int i=0; i < sizeof(strings)/sizeof(string); i++)
{
cout << strings[i] << endl;
}
}
Aardvark
Beetroot
Cabbage
Fox
Zebra