Arrays and Vectors

Hello everyone,

I was just curious as to why I can declare a constant int in int main() and use it to define the size of an array. Example 1:

1
2
3
4
5
6
7
int main()
{
    const int SIZE=5;
    int dataStore[SIZE];
    cout << "Hello world!" << endl;
    return 0;
}


YET, in a class definition, the code does not compile? Example 2:
1
2
3
4
5
6
7
8
9
10
11
12
class Data{
public:
    Data();

private:
    const int SIZE;
    int datStore[SIZE];
};

Data::Data(){
    SIZE=5;
}


Why does the first example produce a valid array while the second example will not compile at all, despite being aesthetically similar?

Sorry for the noob question, but I do appreciate your time.
Last edited on
They're not aesthetically similar.

In the first, you're declaring a constant and giving it a value as you delcare it.
In the second, you're declaring a constant with no value. Then you're trying to assign something to it, which is illegal.

You can't put the constant definition inside the class like that either, it'd need to go outside of it. Or static. I think there might be some sort of C++11 way of doing it non-static, but I couldn't be certain.
Last edited on
In the first example, the compiler knows the value of SIZE.

In the second example, the value of SIZE is undefined when Data is created (but before the constructor is executed.
Last edited on
Thank you for that. I need to be more aware of the compile order.

I suppose this code would be more akin to first example?

1
2
3
4
5
6
7
8
9
10
11
12
13
class Data{
public:
    Data();

private:
    int SIZE;
    int *dataStore;
};

Data::Data(){
    SIZE=5;
    dataStore=new int [SIZE];
}


Would using something like this have any repercussions in regards to processor strain (vs what I have in Example 1)?

Here's another way (that still uses a constant as oppose to the previous example):

1
2
3
4
5
6
7
8
9
#define SIZE 5

class Data{
public:
    Data();

private:
    int dataStore[SIZE];
};
Last edited on
Yep, both valid. I should point out that the only instance of a dynamic array here is the one in which you're using the new array.

If you want dynamically size arrays, I mean arrays that can be sized at run-time, not compile-time, then you should take a look at std::vector.
GNU (gcc, ...) allows the following:

1
2
3
4
5
6
7
8
9
10
11
class Data{
public:
    Data();

private:
    static const int SIZE = 5;
    int datStore[SIZE];
};

Data::Data(){
}


But as iHutch105 said: you should take a look at std::vector.
Last edited on
I suppose this code would be more akin to first example?

No, that's really another animal. In both cases, the Data instance is allocated on the stack. In the latest example, dataStore is allocated from the heap.

Would using something like this have any repercussions in regards to processor strain?

I try not to laugh at questions here, but that one made me chuckle. :) No, allocating something on the heap isn't going to strain the processor. Yes, it does take a few more CPU cycles that the direct allocation on the stack. Even if you're constructing that object millions of times, the difference is so slight you're not likely to notice.

What is critical about the dynamic allocation (new), is that you must always release the dynamically allocated memory in the descructor or you will have a memory leak and will run the risk of exhausting memory available on the heap.
Wow, those are some helpful replies. Thank you all very much!

I have a good bit of experience with vectors; I was just using an array to aid in my transition to vectors as a primary data structure.

I want to understand an array to the best of my ability before I begin going all willy-nilly with vectors (even though I already have been).

I found myself taking a vector (already dynamic) for granted. I wanted to try a using an older container to aid in the learning process.

Again, thank you for the insight. This is my second year with c++ and I find myself growing less concerned with my ability to solve problems, and more concerned with making the fastest possible code.

I need to remember; while one thing may be faster, the difference is so menial it does not matter in real-world implementation.


As an aside: Would creating a vector of a billion++ elements cause more strain than a simple array with the same number of elements? I suppose I could just time it and see...
Last edited on
Would creating a vector of a billion++ elements cause more strain than a simple array with the same number of elements?

A billion? Well now we're talking some possible strain. :)

Here's why and how to avoid it. A vector contains an internally allocated dynamic array. Since vector doesn't normally know in advance how many entries there are going to be it makes a guess. That number is implementation defined, but is usually small (16). When you attempt to push the 17th item onto the vector, the code has to allocate a larger instance of the array (you now have two arrays), copy the existing array to the newly allocated one and then releases the original. This can get quite tedious if you're pushing a billion items (assuming you have the memory to support it). Fortunately vector provides a way to avoid this if you have a good idea of how many items you're going to have in advance.
1
2
  vector<Item>  v;
  v.reserve (1000000000);

This will cause the internal array to be allocated one with sufficient room for 1B items. You'll avoid any reallocation and copying unless you exceed 1B items. Keep in mind that the amount required of memory is 1B * sizeof(Item).
Props, Anon! Great suggestion. I wrote a little program and implemented a vector with a call to the reserve function like you suggested. I also have an array of the same size in there.

I could only fill them with ~2,000,000 before the program stopped responding when I compiled it.

This is probably a horrible representation of the possibilities of these containers, but It was fun none-the-less:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <vector>
#include <time.h>
#define SIZE 2080001

using namespace std;

class Battle{
public:
    Battle();
    void Begin();
    void StartTimer();
    void StopTimer();
    void CreateVector();
    void CreateArray();
private:
    char a[SIZE];
    vector<char>A;
    clock_t start;
    clock_t stop;
    double elapsed;
    char element;
    char choice;
};
//============================================
Battle::Battle(){
    elapsed=0;
    element='a';
    A.reserve(SIZE);
}
//============================================
void Battle::Begin(){
    cout<<"Choose a vector or an array"<<endl<<"(It will be filled with "<<SIZE-1<<" elements and timed.)"<<endl;
    cout<<"Press 1 for a Vector"<<endl<<"Press 2 for an Array"<<endl<<"Press 'q' to quit."<<endl<<endl;
    while(cin>>choice){
        switch(choice){
            case '1':   StartTimer();
                        CreateVector();
                        StopTimer();
                        break;
            case '2':   StartTimer();
                        CreateArray();
                        StopTimer();
                        break;
        }
        if(choice=='q'){
            break;
        }
    }
}
//============================================
void Battle::StartTimer(){
    start=clock();
}
//============================================
void Battle::StopTimer(){
    stop=clock();
    elapsed = ((double) (stop - start) * 1000) / CLOCKS_PER_SEC;
        cout<<"ELAPSED TIME: "<<elapsed<<endl;
    start=0;
    stop=0;
    elapsed=0;
}
//============================================
void Battle::CreateArray(){
    for(unsigned i=0;i<SIZE;i++){
        a[i]=element;
    }
}
//============================================
void Battle::CreateVector(){
    for(unsigned i=0;i<SIZE;i++){
        A[i]=element;
    }
}
//============================================
int main()
{
Battle NOW;
    NOW.Begin();
return 0;
}


Like you said before, the difference is so small it doesn't matter.
Last edited on
Topic archived. No new replies allowed.