Expanding arrays

I have to write a code that expands the array onces it reaches it's max capacity. I tried java and c++. It has to be able to read in int from a file and fill them in the array and once the array in full it expands. I can't get it to work with two arrays so I did this.

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

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    int size = 5;
    int tiny[size];
    int runTime = 0;
    ifstream  input;

  input.open("C:\\info.txt");


    while(!input.eof())
    {
        input >> tiny[size];
        runTime++;
        cout << tiny[size] << endl;//keeping track of the read  in.
        cout << "This is iteration # " << runTime <<endl;//to see where it crashes.
        if(runTime == size - 1)
        {
            size *= 2;
            cout << "I'm too small, growing up" << endl;// need to know if it is expanding.

        }
    }

    input.close();




    return 0;
}



Initailly it made it to the 81st iteration before crashing now it makes it to 21 and crashes. I have no idea why it does this can anyone give me some insight.

Thank you,
Ashley
What you do here is quite dangerous. Try a vector instead, that's exactly what it is designed to do.

http://cplusplus.com/forum/beginner/28299/#msg152150
Hi there,

Your problem is that you are not actually resizing your array you are just writing passed the bounds which is why your application crashes. There isn't actually a way to increase the size of an array at runtime you have to create a new array of equal or greater size and then copy the contents of your old array into the new array.

1
2
3
4
5
6
7
8
9
10
11
12
13
// allocate array...
const int default_size = 10;

int array1[default_size] = {1,2,3,4,5,6,7,8,9,0};

// the array is now full so if we want to add to it we need to create a new array...
int array2[sizeof(array1) + default_size];

// now copy array...
std::memcpy(array2, array1, sizeof(array1));

// free resources...
delete[] array1;


Now obviously this example is pretty useless but it should show that you need to calculate the size of each object in order to know how much more to allocate - don't assume this otherwise you will run into problems.

Additionally allocations are performance heavy so its best to allocate more upfront and then use add items over time than to keep reallocating.

However, I agree with the comment above - you really should be using vectors for this.

I hope this helps.

Phil.


Last edited on
I thought I put it in there I'm not allowed to use vectors for this. And I don't understand how do get a second array to fill with the previous array's contents. The inital array has to be initalized at five and then double in size everytime it reaches capacity. This has to be able to continue infinite ammount of execution.
You need to dynamically allocate arrays to do that. Dynamically allocated arrays are accessed through a pointer. When your container grows beyond the size of the initial array, allocate a new one, copy the old one into it, delete the old one and have the pointer point to the new array. This is what std::vector does internally.
Thank for the info. After looking around this is what I come up with. It make one increase and then times out in the temp array.
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
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    int  size = 5;
    int* tiny = new int [size];
    int runTime = 0;
    ifstream input;

    input.open("C:\\Libraries\\Documents\\info.txt");

    while(!input.eof())
    {
        runTime++;
        input >> tiny[runTime];
        
        cout << tiny[runTime] << endl;//keeping track of the read  in.
        cout << "This is iteration # " << runTime <<endl;//to see where it crashes.
        if(runTime >= size)
        {
            size *= 2;
            int* temp = new int[size];
            cout << "I'm too small, growing up" << endl;// need to know if it is expanding.

            for(int i = 0; i < runTime; i++)
            {
                temp[i] = tiny[i];// I'm getting erronious input in this array
                                          //that doesn't show up in the primary array, then it times out.
            }
            delete [] tiny;
            tiny = temp;
        }
    }

    input.close();




    return 0;
}


Last edited on
This just begs for a class.

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
const unsigned int init_mem = 5;

class MyVector {
public:
    MyVector()
    :size(0), memory(init_mem) { vector = new int[memory]; }

    ~MyVector() { delete[] vector; }

    void push_back(int n);
    int elem(int i) { return vector[i]; }

private:
    void grow();

    int* vector;
    unsigned int size;
    unsigned int memory;
};

void MyVector::push_back(int n)
{
    if(size == memory) grow();
    vector[size] = n;
    ++size;
}

void MyVector::grow()
{
    memory *= 2;
    int* temp = new int[memory];
    for(unsigned int i = 0; i < size; ++i)
    {
        temp[i] = vector[i];
    }
    delete[] vector;
    vector = temp;
}

I haven't tested or compiled this, so there might be bugs. There's a lot of improvements you could (and should) make. For instance, elem() is a clumsy way of accessing elements, and it doesn't do any kind of checking. But this is the general idea. Notice in the code you posted you weren't changing variable size when you read something in.

Another thing is you were looping on eof(), and you shouldn't do this. I'm a little tired of explaining this time and again, but here it goes. First, if you do that, your loop will still execute even if the read fails, as it'll only check for eof() in the next iteration. Second, you're not checking for the other failure states, which are fail() and bad(). Just do this: while(stream >> object).
Topic archived. No new replies allowed.