Hi all.
I've written my own class Complex, that stores complex numbers.
I've overloaded a whole bunch of operators so that you can work with them like with normal numbers.

Then i wanted to overload 'new', but I tried it before overloading, and it "seems" to be working.
I can write

Complex *ptr = new Complex;

And it works so far, but I'm not sure if it allocates enough space?

And delete doesn't work, because data is accessible after using delete.
Should I overload 'delete' and let 'new'? Or overload both?

Member Avatar for jencas

Neither nor. The compiler knows the size of your objects. And delete does work! The memory area just isn't used by other objects.

Neither nor. The compiler knows the size of your objects. And delete does work! The memory area just isn't used by other objects.

Thx, I'm going to do that. But just out of curiosity, let's say i write:

string *ptr = new string;
string *alt = ptr;
ptr->assign("Happy Day");

cout<<"On alt adress is: "<<*alt<<endl;
    
cout<<"deleting ptr"<<endl;
delete ptr;
cout<<"ptr adress: "<<ptr<<endl;
cout<<"alt points to: "<<*alt<<endl;

Now program is terminated as it tries to read *alt (so delete really destroyed contents on that memory location).
If i replace string with my own Complex, it works fine, like it never was deleted.
How did string writers managed to do that?

Member Avatar for jencas

"delete ptr" means "free the memory ptr points to". To avoid invalid access to deleted memory set ptr to 0 after deleting.

delete ptr;
ptr = 0;

I'm aware of that, but that's not the issue here.
If i go with string, when trying to access deleted memory site, OS gives an error (because of pointer accessing something he shouldn't)
If i go with my object, when trying to access deleted memory site, I can access it!

Thx, I'm going to do that. But just out of curiosity, let's say i write:

string *ptr = new string;
string *alt = ptr;
ptr->assign("Happy Day");

cout<<"On alt adress is: "<<*alt<<endl;
    
cout<<"deleting ptr"<<endl;
delete ptr;
cout<<"ptr adress: "<<ptr<<endl;
cout<<"alt points to: "<<*alt<<endl;

Now program is terminated as it tries to read *alt (so delete really destroyed contents on that memory location).
If i replace string with my own Complex, it works fine, like it never was deleted.
How did string writers managed to do that?

ptr and alt point to the same dynamically allocated string. "delete ptr" deletes that string, so it no longer exists (as far as your program is concerned). Any dereferencing of ptr or alt (eg attempting to print *alt) therefore yields undefined behaviour.

Undefined behaviour means - according to the C++ standard - that anything is allowed to happen when the code is compiled/executed. This means that doing it with different types (eg string and your Complex) can exhibit different types of behaviour. Or the same type of behaviour. Or the behaviour can depend on phase of the moon.

As to the actual reason your code terminates with string and not with your Complex type: that depends on your compiler, operating system, etc. In rough terms, it will be because a string type dynamically manages memory (eg it contains a pointer, and allocates/releases memory to that memory) so the act of dereferencing a pointer to a non-existent string and printing it is more likely to walk over random memory than is the act of dereferencing a pointer to a non-existent "Complex". The more rampantly code walks over random memory, the more likely the operating system is to detect that happening, and therefore terminate your program.

I'm aware of that, but that's not the issue here.
If i go with string, when trying to access deleted memory site, OS gives an error (because of pointer accessing something he shouldn't)
If i go with my object, when trying to access deleted memory site, I can access it!

Yes, as grumpier said, when u try to dereferenciate freed memory, if your program crashes or not ... it depends on the type you try to dereferenciate... If you replace string with int in your previsorious example, the program is likely to not crash anymore... it will just read at the supplied mem adress and print what it finds there as an int . After you call delete, the freed memory adress might be set to some default values depending on your compiler, debug/release build, optimization level... or it might be left containging the same values as before so reading that memory adress again and expecting the same type might SEEM that nothing wrong happend. The fact that you deleted that piece of memory means that THAT block can be used for another allocation so might be overwritten at any time. So, everyting is "unexpected" when doing this...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.