473,657 Members | 2,513 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

delete MyClass doing more than MyClass::operat or 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 (nonBaseFunctio n() 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 1878
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 (nonBaseFunctio n() 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
3193
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 of the class. Now this is exactly what I need, most of the time. I've found a couple of instances where I would like to be able to sort (using the 'sort' algorithm) on a different attribute of my class. Is there any other way I can take...
2
4337
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. -- John Mark Howell
7
1706
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; while(...) { list = new char ; strncpy(list, c_TempFilename, Stringlength);
9
325
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 void pointers generally free the memory right?
10
2950
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
478
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
2557
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 about it. I wanted that on my class delete should not work. Object pointer should be deleted using my function only which is taking care of reference count for particular class. Thanx in advance for your inputs.
7
1359
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 'hello world' printed twice. Also if I replace char* with int*, the freeing of memory will generate the second output 0. Why does this happen?? If using int*, freeing of memory means the value is reset to 0, why doesnt the same happen in char * ??
2
3938
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 deallocator like a pool, which makes me to overload the delete operator. Small example of the problem is #include <new> #include <iostream> using namespace std; void operator delete(void* p) { cout << "Hello" << endl; free(p);
0
8413
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8842
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8740
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8617
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6176
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5642
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4330
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2742
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1970
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.