473,404 Members | 2,137 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

delete MyClass doing more than MyClass::operator delete()?

tom
Hi,
I'm overriding my operator new and operator delete for two classes,
one inherited from the other, so I can use my own memory pool. A
simplified version of what I have is below:
class BaseClass {
BaseClass();
virtual ~BaseClass();
virtual void baseFunction();
static void operator delete(void* mem);
};

class InheritedClass : public BaseClass {
IneritedClass();
~InheritedClass();
void baseFunction();
void nonBaseFunction();
static void operator delete(void* mem);
};
I'm testing some things by making operator delete() do nothing, so the
memory shouldn't be deallocated. I've also made the ~BaseClass() and
~InheritedClass() functions do nothing. When I call delete on an
InheritedClass object, if I try to then call any inherited function on
that object (in this example, baseFunction()) I get a crash. If I call
a non-inherited function (nonBaseFunction() in this example) then it
goes along fine and nothing bad happens, as I would epect the inherited
function to have done (since, again, no memory should be deallocated).
In my actual code, I've tested to make sure that the delete call is
actually going through my InheritedClass's operator delete function,
and that it isn't doing anything in the base class's operator delete
function, though both have them defined to do nothing. But it seems
that delete is doing something more than what I define in that
function, and it's messing up things dealing with inheritance. I'm
using Visual Studio 2005. Any ideas would be greatly appreciated.

Tom

Jul 14 '06 #1
5 1864
tom wrote:
I'm overriding my operator new and operator delete for two classes,
one inherited from the other, so I can use my own memory pool. A
simplified version of what I have is below:
class BaseClass {
BaseClass();
virtual ~BaseClass();
virtual void baseFunction();
static void operator delete(void* mem);
};

class InheritedClass : public BaseClass {
IneritedClass();
~InheritedClass();
void baseFunction();
void nonBaseFunction();
static void operator delete(void* mem);
};
I'm testing some things by making operator delete() do nothing, so the
memory shouldn't be deallocated. I've also made the ~BaseClass() and
~InheritedClass() functions do nothing. When I call delete on an
InheritedClass object, if I try to then call any inherited function on
that object (in this example, baseFunction()) I get a crash. If I
call a non-inherited function (nonBaseFunction() in this example)
then it goes along fine and nothing bad happens, as I would epect the
inherited function to have done (since, again, no memory should be
deallocated). In my actual code, I've tested to make sure that the
delete call is actually going through my InheritedClass's operator
delete function, and that it isn't doing anything in the base class's
operator delete function, though both have them defined to do
nothing. But it seems that delete is doing something more than what
I define in that function, and it's messing up things dealing with
inheritance. I'm using Visual Studio 2005. Any ideas would be
greatly appreciated.
Calling non-static member functions for an object after its lifetime
ended has *undefined behaviour* according to the language specification.
What else do you need to know about it?

If you'd like to learn what your code does under the covers, by all
means, explore the generated machine code and make your own conclusions
from that. However, it has no relevance here, in comp.lang.c++. Any
conclusion you make from looking at machine code is only relevant to
your particular platform (hardware and OS) and your particular compiler
implementation.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 14 '06 #2
My guess is that the compiler destroys the vtable on its own. So the
vtable pointer in your object now points to memory that has been
destroyed. Programmers dont have access to the vtable so they cant be
excpected to create and destroy it when writing their own new and
delete. The programmers part is creating or destroying the object, not
its vtable.

Since baseFunction is a virtual function it crashes when trying to
access the vtable, the nonBaseFunction does not use the vtable so does
not crash.

Using an object after calling delete (even an empty one) sure sounds
like undefined behaviour to me.

Then again I'm no expert.

Regards /Petke

Jul 14 '06 #3
tom wrote:

Despite the unfortunate and stupid name, the functions operator new and
operator delete are not the implementation of the new and delete
operators. They are the memory allocator/deallocator functions.
I'm testing some things by making operator delete() do nothing, so the
memory shouldn't be deallocated.
The memory is not deallocationed.
f I try to then call any inherited function on
that object (in this example, baseFunction()) I get a crash.
Unfortunately, just stubbing out the destructors and the delete
operators do not totally negate the operation of the delete
operator.

There are a number of things that happen during initialization
and destruction other than the invocation of the destructor
bodies and the call to operator delete() to return memory.

The truth of the matter as far as the standard is concerned
is that once the objects lifetime is over, you can't do
stuff with it. Yes you could look at the deleted memory
directly, but the object will not necessarily support any
attempts to use it as an object.

I can tell you why it probably blows up in practice, but that
knowledge is dangerous to you. You should not touch the
object after it has been deleted.
If you want to manage an object lifetime, the key is to not
use the allocation / deallocation functions. For instance,
if you want to reference count the object, you just add
functions to INCREASE/DECREASE and let the decrease delete
the object on last use:

class Counted {
public:
Counted() : references(0) { } // init reference count
private:
~Counted() { } // no external destruction.

public:
void AddReference() { ++references; }
void SubReference() { if(--reference == 0) delete this; }
};

If you want to use normal object creation / destruction procedures, you
can wrap this whole thing with a helper object that holds a pointer
to Counted and increases and decreases the reference count in it's
constructors, copy constructor, assignment operator, and destructor.

There's several of these type objects already defined and debugged
for you in the boost library.
Jul 14 '06 #4

Ron Natalie wrote:
tom wrote:

Despite the unfortunate and stupid name, the functions operator new and
operator delete are not the implementation of the new and delete
operators. They are the memory allocator/deallocator functions.
I'm testing some things by making operator delete() do nothing, so the
memory shouldn't be deallocated.

The memory is not deallocationed.
f I try to then call any inherited function on
that object (in this example, baseFunction()) I get a crash.

Unfortunately, just stubbing out the destructors and the delete
operators do not totally negate the operation of the delete
operator.

There are a number of things that happen during initialization
and destruction other than the invocation of the destructor
bodies and the call to operator delete() to return memory.

The truth of the matter as far as the standard is concerned
is that once the objects lifetime is over, you can't do
stuff with it. Yes you could look at the deleted memory
directly, but the object will not necessarily support any
attempts to use it as an object.

I can tell you why it probably blows up in practice, but that
knowledge is dangerous to you. You should not touch the
object after it has been deleted.
If you want to manage an object lifetime, the key is to not
use the allocation / deallocation functions. For instance,
if you want to reference count the object, you just add
functions to INCREASE/DECREASE and let the decrease delete
the object on last use:

class Counted {
public:
Counted() : references(0) { } // init reference count
private:
~Counted() { } // no external destruction.

public:
void AddReference() { ++references; }
void SubReference() { if(--reference == 0) delete this; }
};

If you want to use normal object creation / destruction procedures, you
can wrap this whole thing with a helper object that holds a pointer
to Counted and increases and decreases the reference count in it's
constructors, copy constructor, assignment operator, and destructor.

There's several of these type objects already defined and debugged
for you in the boost library.
Here's a thread on this *interesting* subject:

http://groups.google.com/group/comp....300689619ed391

Jul 14 '06 #5
tom
Ah, thanks so much for this clarification. It is an unfortunate and
stupid name for these operators, I've been using them for a long time
assuming that I was completely overriding the delete functionality and
just now came to a spot where it was clear I wasn't. Very helpful
remarks, thank you all very much!!

Despite the unfortunate and stupid name, the functions operator new and
operator delete are not the implementation of the new and delete
operators. They are the memory allocator/deallocator functions.
Jul 14 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: deancoo | last post by:
Yet another question... I have a container (vector say) containing my class objects. I've overloaded the less than operator in my class definition to allow sorting based on a certain attribute...
2
by: John Mark Howell | last post by:
BlankDoes anyone know how to overload the greater than (>) operator? I know that it is probably not in accordance to the framework design patterns, but it would make my code much cleaner. -- ...
7
by: Nemo | last post by:
Hello Folks, I need to manipulate a list of char strings as follows, but when I want to delete the pointer created with new at the end, delete operator crashes, any idea? char* list;...
9
by: bob | last post by:
Let's say you use the delete operator as follows: Rocket *rocket = new Rocket; void *voidptr = (void *) rocket; delete voidptr; Does the memory get deleted right? Do delete operations on...
10
by: =?iso-8859-1?q?Ernesto_Basc=F3n?= | last post by:
I am implementing my custom smart pointer: template <typename T> class MySmartPtr { public: MySmartPtr(T* aPointer) { mPointer = aPointer; }
5
by: siddhu | last post by:
What happens when deletion falis?Does operator delete function throw exception? I assume that nothrow is not available with delete. Or is it available?
12
by: Premal | last post by:
Hi, I tried to make delete operator private for my class. Strangely it is giving me error if I compile that code in VC++.NET. But it compiles successfully on VC++6.o. Can anybody give me inputs...
7
by: Nishi | last post by:
hi.. I was experimenting with new and delete operators. I ended up getting something I didnt understand. I allocated memory to a char pointer, and even after freeing the memory, I still got...
2
by: kapilkumawat | last post by:
I have an requirement to overload the delete operator in C++, but it should also accept the sizeof() the object that is to be deleted. Actually I am trying to built a custom memory allocator and...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.