Jordan Borisov Jordan Borisov - 4 months ago 13
C++ Question

Different output depending delete

I have this code:

#include <iostream>
using namespace std;
char* pass(char* p){
char* a = new char[10];
a[0] = 'S';
a[1] = 'e';
a[2] = 'r';
a[3] = 'g';
a[3] = 'e';
a[3] = 'y';
a[4] = '\0';
p = a;
//delete [] a;
return p;
}
int main(int argc,char* argv[]){
char* p1 = new char[1000];
p1[0] = 'G';
p1[1] = 'e';
p1[2] = 'r';
p1[3] = 'y';
p1[4] = '\0';
char* p2 = p1;
cout << p2 << endl;
cout << pass(p2) << endl;
delete [] p1;
}


and the output is :

Gery
Sery


but if I uncomment the line
delete [] a

I got this output :

Gery
ê§É


Why?

Answer

In this function

char* pass(char* p){
    char* a = new char[10];
    a[0] = 'S';
    a[1] = 'e';
    a[2] = 'r';
    a[3] = 'g';
    a[3] = 'e';
    a[3] = 'y';
    a[4] = '\0';
    p = a;
    //delete [] a;
    return p;
}

the parameter is a local variable of the function. After exiting the function it is destroyed.

You can imagine the function and its call the following way

pass(p2);

char* pass(/*char* p*/){
    char* p = p2;
    char* a = new char[10];
    a[0] = 'S';
    a[1] = 'e';
    a[2] = 'r';
    a[3] = 'g';
    a[3] = 'e';
    a[3] = 'y';
    a[4] = '\0';
    p = a;
    //delete [] a;
    return p;
}

As you see the original pointer p2 will not be changed in the function. The function changes its local variable p that is declared as a parameter.

If to uncomment the delete statement then the memory pointed to by the return value will be deleted and the returned pointer will be invalid. In this case the program has undefined behaviour due to statement

cout << pass(p2) << endl;

where there is an attempt to access the deleted memory using the return value of the function.

So there is no sense to return pointer to deleted memory.

What you want to do can be achieved in three ways

The first one is to declare the parameter as reference

char* pass(char* &p){
           ^^^^^^^^
    char* a = new char[10];
    a[0] = 'S';
    a[1] = 'e';
    a[2] = 'r';
    a[3] = 'g';
    a[3] = 'e';
    a[3] = 'y';
    a[4] = '\0';
    p = a;
    return p;
}

and call the function like

cout << pass(p2) << endl;

The second one is to declare the parameter as pointer to pointer that is to accept the original pointer indirectly

char* pass(char* *p){
           ^^^^^^^^
    char* a = new char[10];
    a[0] = 'S';
    a[1] = 'e';
    a[2] = 'r';
    a[3] = 'g';
    a[3] = 'e';
    a[3] = 'y';
    a[4] = '\0';
    *p = a;
    ^^^^^^^^
    return *p;
    ^^^^^^^^^^
}

and call the function like

cout << pass(&p2) << endl;

And at last you could simply assign the returned value to the original pointer. For example

char* pass(char* p){
    char* a = new char[10];
    a[0] = 'S';
    a[1] = 'e';
    a[2] = 'r';
    a[3] = 'g';
    a[3] = 'e';
    a[3] = 'y';
    a[4] = '\0';
    p = a;
    return p;
}

and call the functionj like

cout << ( p2 = pass(p2) ) << endl;

In any case you should delete the allocated memory at the end of the program like

delete [] p2;
Comments