Cihad Turhan
Cihad Turhan

Reputation: 2849

Isn't it ok in terms of memory leakage etc

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

Answers (6)

Luchian Grigore
Luchian Grigore

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

moshbear
moshbear

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

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

unkulunkulu
unkulunkulu

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

Armen Tsirunyan
Armen Tsirunyan

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

Roman Ryltsov
Roman Ryltsov

Reputation: 69706

  1. by assigning to firstPtr to will be unable to free memory behind the overwritten pointer
  2. deleting tempPtr you make data pointed to by firstPtr invalidated (the immedaite cause of wrong output)

Solution:

  1. add line to delete firstPtr before assignment line "firstPtr = tempPtr;"
  2. move line that deletes tempPtr below "cout <<" loop

Upvotes: 1

Related Questions