Reputation: 2849
It's been about 2 months since I started to learn c++ and I'm not quite sure about I'm doing wrong for my project. I have a dynamically allocated array with an initial size and after I want to change the size of it. The thing I wonder is why the following code is wrong
int *firstPtr = new int [4];
for (int i = 0; i < 4; i++) {
firstPtr[i] = i;
}
int *tempPtr = new int[5];
for (int i = 0; i < 4; i++) {
tempPtr[i] = firstPtr[i];
}
tempPtr[4] = 4;
// firstPtr = new int[5];
firstPtr = tempPtr;
delete tempPtr;
for (int i = 0; i < 5; i++) {
cout << firstPtr[i] << endl;
}
because the output is:
10757752
10753936
2
3
4
PS: I can't use realloc/malloc etc for this since the project is just about pointers. How can I correct this without them.
Upvotes: 1
Views: 114
Reputation: 258618
firstPtr = tempPtr;
first Ptr now points to the same memory as tempPtr.
delete tempPtr;
You are now deleting that memory, the same memory both firstPtr and tempPtr are pointing to.
for (int i = 0; i < 5; i++) {
cout << firstPtr[i] << endl;
}
You are accessing deleted memory, the values printed can be anything.
To get what I'm assuming you want, you need to remove the line
firstPtr = tempPtr;
or delete the memory after the for:
for (int i = 0; i < 5; i++) {
cout << firstPtr[i] << endl;
}
delete[] tempPtr;
Note that in the second case you will get a memory leak, since the memory initially pointed to by firstPtr
is no longer accessible.
A complete working and correct code would be as follows:
int *firstPtr = new int [4];
for (int i = 0; i < 4; i++) {
firstPtr[i] = i;
}
int *tempPtr = new int[5];
for (int i = 0; i < 4; i++) {
tempPtr[i] = firstPtr[i];
}
tempPtr[4] = 4;
for (int i = 0; i < 5; i++) {
cout << firstPtr[i] << endl;
}
delete[] tempPtr;
delete[] firstPtr;
Some ASCII art:
firstPtr = new int[4];
firstPtr
|
+------++------++------++------+
| || || || |
| || || || |
+------++------++------++------+
for (int i = 0; i < 4; i++) {
firstPtr[i] = i;
}
firstPtr
|
+------++------++------++------+
| 0 || 1 || 2 || 3 |
| || || || |
+------++------++------++------+
int *tempPtr = new int[5];
for (int i = 0; i < 4; i++) {
tempPtr[i] = firstPtr[i];
}
tempPtr[4] = 4;
tempPtr
|
+------++------++------++------++------+
| 0 || 1 || 2 || 3 || 4 |
| || || || || |
+------++------++------++------++------+
So now, in memory, you have:
firstPtr
|
+------++------++------++------+
| 0 || 1 || 2 || 3 |
| || || || |
+------++------++------++------+
tempPtr
|
+------++------++------++------++------+
| 0 || 1 || 2 || 3 || 4 |
| || || || || |
+------++------++------++------++------+
Your next line:
firstPtr = tempPtr;
does this:
no longer pointed to by firstPtr
|
+------++------++------++------+
| 0 || 1 || 2 || 3 |
| || || || |
+------++------++------++------+
tempPtr
firstPtr - firstPtr now points here
|
+------++------++------++------++------+
| 0 || 1 || 2 || 3 || 4 |
| || || || || |
+------++------++------++------++------+
delete tempPtr;
tempPtr
firstPtr - firstPtr now points here
|
+------++------++------++------++------+
| x || x || x || x || x |
| || || || || |
+------++------++------++------++------+
So now, tempPtr points to delete memory. Hope this clears things up.
Upvotes: 3
Reputation: 3322
You're accessing deleted memory. This is undefined behavior.
This is similar to reading a value from a malloc()
ed pointer after free()
has been called.
Upvotes: 0
Reputation: 1
firstPtr = tempPtr;
delete tempPtr;
Then you use firstPtr
but it is the same as tempPtr
which is a pointer that you deleted.
Try drawing on paper what is happenning inside your heap to understand.
Upvotes: 0
Reputation: 11922
It's here
firstPtr = tempPtr;
delete tempPtr;
you see, you assign the value of tempPtr
to firstPtr
, which means that they're referring to the same memory location (at this point you have no pointer to the old memory, which used to be pointed to by firstPtr
), then you deallocate (delete
) the memory pointed-to by tempPtr
, which is the same memory actually.
The correct way should be
delete firstPtr;
firstPtr = tempPtr;
Upvotes: 1
Reputation: 133072
Instead of
firstPtr = tempPtr;
delete tempPtr;
You need
delete [] firstPtr;
firstPtr = tempPtr;
And later, after you're done, don't forget
delete [] firstPtr;
In your original post you first have your firstPtr point at the newly allocated memore, then free it. So both firstPtr and tmpPrt point at freed memory. Using freed memory is Undefined Behavior. Also, please consider using std::vector<int>
s. That will make your life easier.
Upvotes: 0
Reputation: 69706
firstPtr
to will be unable to free memory behind the overwritten pointertempPtr
you make data pointed to by firstPtr
invalidated (the immedaite cause of wrong output)Solution:
firstPtr
before assignment line "firstPtr = tempPtr;"tempPtr
below "cout <<" loopUpvotes: 1