# Thread: Problem with Dynamically Increasing Array of Integers

1. >No, because enlarge() is called before arr[size] is used, i.e. we enlarge first then use.
The problem is arrays run from 0 to size-1, so if size is 4 you are already writing one past the array. For example:
Code:
`			arr[size++] = temp;`
If size is 4 before this statement, and your array is 4 elements, you already need to enlarge the array, because there is no:
Code:
`arr[4]`
There's only arr[0] thru arr[3].

2. Code:
```         if ( size >= max_size )
{
enlarge(arr, max_size);
cout << "max_size = " << max_size << endl;
}
cout << "size = " << size << endl;
(*arr)[size++] = temp;```
Code:
```/* my output
size = 0
size = 1
size = 2
size = 3
size = 4
size = 5
size = 6
size = 7
size = 8
size = 9
max_size = 20
size = 10
size = 11
*/```

3. laserlight, why do you have this line of code in your enlarge() function:
Code:
`temp = 0;`
?
memory allocated to temp has already been delete[]d and temp itself will go out of scope the next line of code.

4. If size is 4 before this statement, and your array is 4 elements, you already need to enlarge the array
That's true.
But if my array is 4 elements in capacity, then max_size = 4.
If size = 4, then size >= max_size, hence enlarge() is called and max_size will be 8 by the time we get to the statement in question.
So my array will be more than 4 elements in capacity, and we dont get an array out of bounds problem, as Dave_Sinkula has kindly shown.

laserlight, why do you have this line of code in your enlarge() function:
Residue from working in a separate test, but it doesnt hurt so I just left it there.
It is good practice to zero deleted pointers anyway.

5. Originally Posted by laserlight
That's true.
But if my array is 4 elements in capacity, then max_size = 4.
If size = 4, then size >= max_size, hence enlarge() is called and max_size will be 8 by the time we get to the statement in question.
So my array will be more than 4 elements in capacity, and we dont get an array out of bounds problem, as Dave_Sinkula has kindly shown.
You're right Lasarlight. I was wrong. I looked it over again last night per Dave's posting and realized I had made a mistake, and that the resizing is occuring at the right time.

6. Well, sorry for bringing up an old post... I just got a little too obsessed with it.
Laserlight's code are pretty much fine I think.

It's okay to change the value of array, as long as you doesent try to give value to something which has been deleted, without calling new first.
An example:
Code:
```int *array = new int[MAX_SIZE];
delete[] array;
array = new int[MAX_SIZE];
*and use it however you'd like*```
This is entirely legal, and arent the problem.
Also, you can call delete on the same pointer-variable, as long as it's either 0, or a new has been called first.
Laserlight does this correctly, and arent the problem either.

The correct solution for this problem is change
Code:
```ifstream& readInput(ifstream& ifs, int arr[], int& size, int& max_size);
template<typename T> void enlarge(T* array, int& size);```
to this:
Code:
```ifstream& readInput(ifstream& ifs, int *&arr, int& size, int& max_size);
template<typename T> void enlarge(T *&array, int& size);```
In short: when you use "new" inside functions and wanna send the pointer out through references, you gotta write:
Code:
`type *&variableName;`
This reads: "variableName are a refference to a pointer to type"

If you do this, your original code works fine, and no need to use the delete [] by adress

7. Well, sorry for bringing up an old post... I just got a little too obsessed with it.
I wonder why

If you do this, your original code works fine, and no need to use the delete [] by adress
Of course, the delete[] is still needed for the original array. However, my original code does alot of unnecessary work. A more efficient implementation would be:
Code:
```template<typename T>
void enlarge(T*& array, size_t& size)
{
size_t new_size = size + size;
T* temp = new T[new_size];
for (size_t i = 0; i < size; ++i)
{
temp[i] = array[i];
}
delete[] array;
size = new_size;
array = temp;
}```

8. I wonder why
It often happens on problems I actually have a chance of solving...
And for some reason I don't even know my self, I was looking at threads that you had started

The new code looks more smooth indeed

But strictly speaking: Shouldn't you error-check after calls to new, in case you're out of memory? I've read that it's compiler-dependent wether you get an error, or if you just get 0.
So something like this?

Code:
```int *iArray = new int[MAX_SIZE];
if(iArray == 0) { //If this is true, you're out of memory
...
}```

9. But strictly speaking: Shouldn't you error-check after calls to new, in case you're out of memory? I've read that it's compiler-dependent wether you get an error, or if you just get 0.
std::bad_alloc will be thrown if memory cannot be allocated. As such, I am letting the exception propagate out from the function, but also carefully making sure that I do not change array and size until I am certain that no exception will be thrown.

10. No, new throws an exception. The enlarge function cannot do anything about it. It's the task of the caller of this function to catch the exception and decide what to do (the array so far remains intact but obviously you cannot append to it since making more room failed).

11. ok..now I'm a little confused.

http://msdn.microsoft.com/en-us/libr...ba(VS.80).aspx
In MSDN it says:
If unsuccessful, new returns zero or throws an exception

Though, it also states that:
You can change this default behavior by writing a custom exception-handling routine and calling the _set_new_handler run-time library function with your function name as its argument.

12. Yes, and it also links to The new and delete Operators, which explains the part that confuses you.

13. well...I read that too, and I'm still somewhat confused as to how to really code a secure example using new.

14. well...I read that too, and I'm still somewhat confused as to how to really code a secure example using new.
What do you find confusing now?

15. Well, not confusing, but I'm uncertain of how you'd make the try-catch, where you would use it , and such.

Is it just like java?
(It would then be like this
Code:
```try {
int *pointer = functionThatUseNew();