Deleting pointers of primitive types

Hi all,

The following code:
1
2
3
4
5
6
7
8
9
10
 Vehicle* toyota = new Vehicle();
    toyota->x = 3;
    cout << "Address of pointer: " << toyota << endl;
    cout << "Content: " << toyota->x << endl;
    cout << "Delete pointer." << endl;
    delete toyota; //delete toyota pointer
    cout << "Address of pointer: " << toyota << endl;
    cout << "Content: " << toyota->x << endl;
    toyota = NULL;
    cout << "Address:" << toyota;

Prints this:

Address of pointer: 0x3e1050
Content: 3
Delete pointer.
Address of pointer: 0x3e1050
Content: 4077312 //Makes sense
Address:0


I expected that to happen.
However, if I try the following code:
1
2
3
4
5
6
7
8
9
10
11
12
int i = 3;
    int *p;
    p = &i; //p has the value 3

    cout << "Address of pointer: " << p << endl;
    cout << "Content: " << *p<< endl;
    cout << "Delete pointer." << endl;
    delete p; //delete toyota pointer
    cout << "Address of pointer: " << p << endl;
    cout << "Content: " << *p << endl;
    p = NULL;
    cout << "Address:" << p<<endl;


It prints this:

Address of pointer: 0x22fe84
Content: 3
Delete pointer.
Address of pointer: 0x22fe84
Content: 3 //Strange
Address:0


The latter doesn't make any sense to me. Why is the content after deleting the pointer still 3? I know it is deallocating memory, but how does it still know the content and why doesn't it know the content of the vehicle after deleting it?
In your first example, you dynamically requested memory through the use of the
new
keyword. The delete keyword then frees the memory created by new.

The second example doesn't dynamically allocate any memory. It simply assigns a pointer (p) to the address of i. Deleting p is therefore not freeing any dynamically allocated memory, so it can still be dereferenced.
Last edited on
In the first snippet, line 8 results in undefined behavior, so the output is irrelevant. Once a pointer has been deleted, it may not be dereferenced until it is made to point at some valid memory location.

In the second snippet line 8 results in undefined behavior, so the output is irrelevant. You may not delete memory that has not been allocated with new.

Don't do stuff that invokes undefined behavior.
Last edited on
Thanks for the comments guys. I appreciate it.

So now I understand that you should only use ''delete'' if you used ''new''?

I thought that you should delete every pointer.
Should I be nulling the pointer (if I don't use delete)?
Not necessarily. Nulling isn't required for the situations in your code. Using NULL comes in handy for more intricate operations, such as initializing default value for a pointer member of a class constructor or managing nodes within a linked list.


If you don't use the pointer again, then don't worry about its value. If you're reusing it, however, then setting it to NULL to indicate that it is currently invalid is a good idea. This really only applies to pointers in classes though, not pointers you create and use in a single function.
> If you're reusing it, however, then setting it to NULL to indicate that it is currently invalid is a good idea.

Automating the nulling of a pointer on delete is trivial.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

template < typename PTR > inline
void do_delete( PTR&& pointer ) { delete pointer ; pointer = nullptr ; }

template < typename PTR > inline
void do_delete_array( PTR&& pointer ) { delete[] pointer ; pointer = nullptr ; }

int main ()
{
    int* p = new int{} ;
    do_delete(p) ;

    int** a = new int* [5] {0} ;

    a[3] = new int {40} ;
    do_delete(a+3) ;

    do_delete_array(a) ;
}


However, it doesn't buy very much; pointers are often aliased.
The canonical C++ way is to use smart pointers, std::vector<> etc. where ever possible.
Topic archived. No new replies allowed.