# Problem with Dynamically Increasing Array of Integers

Show 80 post(s) from this thread on one page
Page 1 of 3 123 Last
• 05-23-2005
laserlight
Problem with Dynamically Increasing Array of Integers
After I discovered about C++ standard vectors, I've been using them ever since.
But just today a friend of mine, who is just learning C++, asked me about dynamically increasing the size of arrays.

Now, I happily went to code an example.
The program reads a file for a whitespace separated arbitrary length list of integers, saves it into an array, then prints the contents of the array. Simple enough.
Now, I discovered that for some reason, the first element in the array always became set to 0.
In particular, it's value is detected to be 0 just after the portion of code that enlarges the array.

In case I got the array expansion wrong, I checked with another friend, who duly provided me with a template function that pretty much did the same thing as I was doing.
Consequently, there was no change in result - the first element remained zeroed.

Here's is the source file in question:
Code:

```#include <iostream> #include <fstream> using namespace std; ifstream& readInput(ifstream& ifs, int arr[], int& size, int& max_size); template<typename T> void enlarge(T* array, int& size) {         int init_size = size;         T* temp = new T[init_size];         for (int i = 0; i < init_size; ++i)                 temp[i] = array[i];         delete[] array;         size += size;         array = new T[size];         for(int i = 0; i < init_size; ++i)                 array[i] = temp[i];         delete[] temp;         temp = 0; } int main() {         int max_size = 10;         int* arr = new int[max_size];         int size = 0;         ifstream ifs("test.txt");         if (ifs.good())                 readInput(ifs, arr, size, max_size);         ifs.close();         for (int i = 0; i < size; i++)                 cout << arr[i] << endl;         delete[] arr;         arr = 0;         cin.sync();         cin.get();         return 0; } ifstream& readInput(ifstream& ifs, int arr[], int& size, int& max_size) {         while (ifs.good()) {                 int temp;                 if (ifs >> temp) {                         if (size >= max_size) {                                 enlarge(arr, max_size);                         }                         arr[size++] = temp;                 }         }         ifs.clear();         return ifs; }```
Here is the input file, named test.txt
Code:

```11 52 6 7 8 2 3 5 7 2 33 4```
The compiler I used is the MinGW port of GCC 3.4.2 (i.e. g++), under the Dev-C++ IDE (Windows XP, no SP2)
Running the program produces each integer on its own line, except that "11" is printed as "0".
My debugging tests show that the value of arr[0] changes to 0 just after enlarge(arr, max_size).
Within the template function itself I detected no anomaly.

Does anyone have any idea what is the problem, and how to fix it?
Thanks.
• 05-23-2005
Darryl
arr[size++] = temp;

your increment here "fully" completes within the brackets and thus the first pass through skips arr[0]
• 05-23-2005
laserlight
Quote:

your increment here "fully" completes within the brackets and thus the first pass through skips arr[0]
I'm using post-increment, not pre-increment, so that should not be the case.
• 05-23-2005
Dave_Sinkula
Code:

```template<typename T> void enlarge(T* array, int& size) { //... array = new T[size];```
If you want to change the value of a pointer within a function and preserve that value outside the function, what do you have to do?
• 05-23-2005
laserlight
I thought I know, but after trying this out I dont.
• 05-23-2005
Dave_Sinkula
Pass a pointer to a pointer or return the pointer value.
• 05-23-2005
laserlight
hmm... just thought of that, but my implementation gives me a runtime error.
Code:

```template<typename T> void enlarge(T** array, int& size) {         int init_size = size;         T* temp = new T[init_size];         for (int i = 0; i < init_size; ++i)                 temp[i] = **(array+i);         delete[] *array;         size += size;         *array = new T[size];         for(int i = 0; i < init_size; ++i)                 **(array+i) = temp[i];         delete[] temp;         temp = 0; }```
Of course I passed the address of arr to the enlarge() call.
• 05-23-2005
hk_mp5kpdw
Code:

```template<typename T> void enlarge(T** array, int& size) {     int init_size = size;     T* temp = new T[init_size];     for (int i = 0; i < init_size; ++i)         temp[i] = **(array+i);     delete[] *array;     size += size;     *array = new T[size];     for(int i = 0; i < init_size; ++i)         **(array+i) = temp[i];     delete[] temp;     temp = 0; }```
Play around with the order of your parenthesis there... you'll get it.
• 05-23-2005
laserlight
Yeah, a change to:
Code:

```template<typename T> void enlarge(T** array, int& size) {         int init_size = size;         T* temp = new T[init_size];         for (int i = 0; i < init_size; ++i)                 temp[i] = (*array)[i];         delete[] *array;         size += size;         *array = new T[size];         for(int i = 0; i < init_size; ++i)                 (*array)[i] = temp[i];         delete[] temp;         temp = 0; }```
solves the runtime error, but doesnt solve the problem.

Now my output is:
Code:

```0 52 6 7 8 2 3 5 7 2 393220 524544```
which seems to indicate garbage after the initial max_size number of elements, while the first element remains zeroed.
• 05-23-2005
Dave_Sinkula
Quote:

Originally Posted by laserlight
Of course I passed the address of arr to the enlarge() call.

Do you do the same with readInput so that the change is noted in main, where the values are displayed?
• 05-23-2005
laserlight
Okay, now here's the funny part.
This implementation of the template function gives the correct output:
Code:

```template<typename T> void enlarge(T* array, int& size) {         int init_size = size;         T* temp = new T[init_size];         for (int i = 0; i < init_size; ++i)                 temp[i] = array[i];         delete[] &array;         size += size;         array = new T[size];         for (int i = 0; i < init_size; ++i)                 array[i] = temp[i];         delete[] temp;         temp = 0; }```
But I didnt pass a pointer to a pointer, as far as I can see.
All I did was delete[] based on address.
Why and how does it work, if it actually works rather than just happen to work?
• 05-23-2005
laserlight
Quote:

Do you do the same with readInput so that the change is noted in main, where the values are displayed?
Good point.
Made the fix and that corrected it.

I understand roughly what's behind passing the pointer to a pointer method, but now I dont understand the delete[]ing by address method, if it is even valid.
• 05-23-2005
Dave_Sinkula
Quote:

Originally Posted by laserlight
but now I dont understand the delete[]ing by address method, if it is even valid.

Slap a couple of these kind of things around key places in the code, such as at each function's entry and exit, to show what the pointer value actually is:
Code:

`cout << "array = " << array << endl;`
If the value of array does change, and you discard the new value, you will be seeing undefined behavior (which unfortunately sometimes appears to be doing what it should).

Only delete[] what was new[]'d exactly once.
• 05-23-2005
swoopy
> if (size >= max_size) {
> enlarge(arr, max_size);
> }
Here you should really have:
Code:

```                        if (size+1 >= max_size) {                                 enlarge(arr, max_size);                         }```
Otherwise you're overflowing your array before you enlarge it.
• 05-23-2005
laserlight
Quote:

If the value of array does change, and you discard the new value, you will be seeing undefined behavior (which unfortunately sometimes appears to be doing what it should).
Yep, it changes right after array = new T[size];
I'll just use the pointer to pointer method then.

Quote:

Otherwise you're overflowing your array size before you enlarge it.
No, because enlarge() is called before arr[size] is used, i.e. we enlarge first then use.
Show 80 post(s) from this thread on one page
Page 1 of 3 123 Last