Differentiate between static and dynamic allocated objects

J

Jo

Hi,

How can i differentiate between static and dynamic allocated objects?

For example:

void SomeFunction1() {

CObject *objectp = new CObject;
CObject object;

SomeFunction2(objectp,&object);
}

void SomeFunction2(CObject *op1,CObject *op2) {

// now how do i know whether op1/op2 was statically or dynamically
allocated?
// and thus whether i may call a 'delete' on it?

}

Thanks,

Jo
 
M

Mike Wahler

Jo said:
Hi,

How can i differentiate between static and dynamic allocated objects?

For example:

void SomeFunction1() {

CObject *objectp = new CObject;
CObject object;

SomeFunction2(objectp,&object);
}

void SomeFunction2(CObject *op1,CObject *op2) {

// now how do i know whether op1/op2 was statically or dynamically
allocated?

You don't, unless you keep track of it yourself. The language
does not provide a way. IMO the introduction of such a need
indicates a poor design.
// and thus whether i may call a 'delete' on it?

It's your responsibility to keep track of what you're doing.
If you allocate something with 'new', you must release it
with 'delete'.

You can reduce the need to keep track of such things by
encapsulating your use of dynamic allocation, don't use
'new' indiscriminately. In my experience, I often see folks
using dynamic allocation when there's really no need. If you
think there is really a need, consider using smart pointers.

For those cases where you need a collection (e.g. array) of
objects whose size will not be known until run-time, look into
using the standard library containers (e.g. std::vector, std::list,
etc.)

-Mike
 
S

Salt_Peter

Jo said:
Hi,

How can i differentiate between static and dynamic allocated objects?

For example:

void SomeFunction1() {

CObject *objectp = new CObject;
CObject object;

SomeFunction2(objectp,&object);
}

void SomeFunction2(CObject *op1,CObject *op2) {

// now how do i know whether op1/op2 was statically or dynamically
allocated?
// and thus whether i may call a 'delete' on it?

}

Thanks,

Jo

Thats your responsability. In the same breath that the CObject labelled
as object is a local variable in SomeFunction1(). Remember: new removes
all responsability the compiler has to destroy / recover that
allocation. You've dissmissed the compiler's duties.

There is a lot you can do to help. One might be to use a smart pointer
instead of new/delete. Another is to not allocate as its not required
in the example given. Properly naming your objects goes a long way too.
And in the case you do choose to new and delete, don't give one
function or class the responsability to new and another function or
class the responsabilty to delete (distribute allocations as a
responsability to one entity only - that is a sacred law, it can't be
over-emphasized).

void SomeFunction1() {
CObject *p_object = new CObject;
CObject object;

SomeFunction2( *p_object, object );

delete p_object;
}

void SomeFunction2( CObject& op1, CObject& op2 ) {
// now how do i know whether...
// answer: its not my responsability
}

pass arguements by reference, not pointers
and pass by const reference if you aren't modifying the args

Theres more, you can load CObjects in a std::vector. Assuming that
CObject is copyable and assignable.
#include <vector>
std::vector< CObject > vobj(1000000); // one million default CObjects
 
J

Jo

Hey,

Thanks for your opinions.

The reason why i want to differentiate between static and dynamic
objects is because of a standard reference counting system.

Each object in the system has a reference count, initially 0 at
construction time.
When the object is used, the reference count is incremented; when it's
released the ref count is decremented.
When the object's ref count gets 0 again, it's automatically deleted.

Simple code:

class CObject {

int RefCount;

CObject() { RefCount=0; }
void Lock() { RefCount++; }
void Unlock() { RefCount--; if (RefCount<=0) delete this; }
};


But what if the object is statically allocated?! Then it may not be
deleted via 'delete' of course.

Whether some objects are allocated dynamically or statically just
depends on the situation, and on the object itself too. (note that the
above class may be a very base class). I don't think it's a matter of
poor design.

So that's in fact why i've put the question.

If i understand your answers well, i could make the CObject class like this:

class CObject {

int RefCount;
bool IsStatic;

CObject() { RefCount=0; }
void Lock() { RefCount++; }
void Unlock() { RefCount--; if (RefCount<=0 && !IsStatic)
delete this; }
void MarkAsStatic() { IsStatic=true; }
};


And then everywhere in the code where an object is allocated statically,
a line must be added: object.MarkAsStatic();

Is that correct? Aren't there any simpler alternatives?

Or is there something wrong with my the design of this ref-counting system?

Cheers,

Jo
 
J

Jo

Jo said:
If i understand your answers well, i could make the CObject class like
this:

class CObject {

int RefCount;
bool IsStatic;

CObject() { RefCount=0; }
void Lock() { RefCount++; }
void Unlock() { RefCount--; if (RefCount<=0 && !IsStatic)
delete this; }
void MarkAsStatic() { IsStatic=true; }
};

Of course, IsStatic should also be initialised in the constructor, in
this case:

CObject() { RefCount=0; IsStatic=false; }
 
T

Thomas Kowalski

Hello Jo,
this resembles to some implementations of smart pointers. Maybe you
should take a look at boost or also the *_var type in Corba (e.g.
ACE/TAO).
If non of these might help you, I guess the best they is encapsulating
the reference counting in a template wrapper class. You might use
template specialization to discriminate between pointer types and
dynamic allocations.

Regards,
Thomas Kowalski
 
S

Salt_Peter

Jo said:
Hey,

Thanks for your opinions.

The reason why i want to differentiate between static and dynamic
objects is because of a standard reference counting system.

Each object in the system has a reference count, initially 0 at
construction time.

A reference counting mechanism should be held by a smart_ptr or the
equivalent thereof. Otherwise you'll end up with 2 distinct
implementations of the CObject class.
When the object is used, the reference count is incremented; when it's
released the ref count is decremented.
When the object's ref count gets 0 again, it's automatically deleted.

Simple code:

class CObject {

int RefCount;

CObject() { RefCount=0; }
void Lock() { RefCount++; }
void Unlock() { RefCount--; if (RefCount<=0) delete this; }
};


But what if the object is statically allocated?! Then it may not be
deleted via 'delete' of course.

The above can be done with a smart_ptr. The smart_ptr does the
reference counting and deletion of the object it is tracking. It zaps
the Object when appropriate. You would not design a class with a
reference count if you where to allocate the class on the stack and on
the heap.

The goal here is to give another object the duty of tracking a
reference count. The advantage is evident: you could ref_count any
type, not just CObject.

By the way, CObject should be called Object (we know its a class, thats
what C stands for).
Whether some objects are allocated dynamically or statically just
depends on the situation, and on the object itself too. (note that the
above class may be a very base class). I don't think it's a matter of
poor design.

So that's in fact why i've put the question.

If i understand your answers well, i could make the CObject class like this:

class CObject {

int RefCount;
bool IsStatic;

CObject() { RefCount=0; }
void Lock() { RefCount++; }
void Unlock() { RefCount--; if (RefCount<=0 && !IsStatic)
delete this; }
void MarkAsStatic() { IsStatic=true; }
};


And then everywhere in the code where an object is allocated statically,
a line must be added: object.MarkAsStatic();

Is that correct? Aren't there any simpler alternatives?

Consider boost's shared_ptr, its heavily used in modern C++. Very
simple to use and rock solid.
You can always write your own reference counting smart_ptr. It just
doesn't make sense to write a smart_ptr that only deals with Objects.
I'ld strongly recommend boost's shared_ptr for this purpose. Its
copyable and therefore can be used in STL containers (unlike <memory>'s
std::auto_ptr).

http://www.boost.org/libs/smart_ptr/shared_ptr.htm

#include <boost/shared_ptr.hpp>

int main()
{
boost::shared_ptr< CObject > sp_obj( new CObject ); // ref counted
Object

typedef boost::shared_ptr< CObject > SPtr_Obj;
// a container of shared_ptrs to Objects
std::vector< SPtr_Obj > v;
v.push_back( SPtr_Obj(new CObject) );
}

The CObject instance at sp_obj will get automatically zapped at the end
of main(). The instance of CObject in the std::vector will
automatically get zapped when the vector is itself destroyed.
That basicly gives the responsability of allocation/deallocation to the
smart_ptr. And your Object class needs not be modified in any way.

Yes, you can have a Cake and eat it too.
Or is there something wrong with my the design of this ref-counting system?

Cheers,

Jo




--------------020901060602050002080207
Content-Type: text/html
X-Google-AttachSize: 4644

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
<tt>Hey,<br>
<br>
Thanks for your opinions.<br>
<br>
The reason why i want to differentiate between static and dynamic
objects is because of a standard reference counting system.<br>
<br>
Each object in the system has a reference count, initially 0 at
construction time.<br>
When the object is used, the reference count is incremented; when it's
released the ref count is decremented.<br>
When the object's ref count gets 0 again, it's automatically deleted.<br>
<br>
Simple code:<br>
<br>
</tt>
<blockquote><tt>class CObject {</tt><br>
<br>
<tt>&nbsp; int RefCount;</tt><br>
<br>
<tt>&nbsp; &nbsp; &nbsp;&nbsp; </tt><tt>CObject() { </tt><tt>RefCount=0; }</tt><br>
<tt>&nbsp; void Lock()&nbsp;&nbsp;&nbsp; { </tt><tt>RefCount++; }</tt><tt></tt><br>
<tt>&nbsp; void Unlock()&nbsp; { </tt><tt>RefCount--; if (RefCount&lt;=0)
delete this; }</tt><br>
<tt>};</tt><br>
</blockquote>
<tt><br>
But what if the object is statically allocated?! Then it may not be
deleted via 'delete' of course.<br>
<br>
W</tt><tt>hether some objects are allocated dynamically or statically</tt><tt>
just depends on the situation, and on the object itself too. (note that
the above class may be a very base class). </tt><tt>I don't think it's
a matter of poor design.</tt><br>
<tt><br>
So that's in fact why i've put the question.<br>
<br>
If i understand your answers well, i could make the CObject class like
this:<br>
<br>
</tt>
<blockquote><tt>class CObject {</tt><br>
<tt></tt><br>
<tt>&nbsp; int&nbsp; RefCount;</tt><br>
<tt>&nbsp; bool IsStatic;</tt><br>
<tt></tt><br>
<tt>&nbsp; &nbsp; &nbsp;&nbsp; </tt><tt>CObject()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </tt><tt>RefCount=0; }</tt><br>
<tt>&nbsp; void Lock()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </tt><tt>RefCount++; }</tt><br>
<tt>&nbsp; void Unlock()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </tt><tt>RefCount--; if (RefCount&lt;=0
&amp;&amp; !</tt><tt>IsStatic</tt><tt>) delete this; }</tt><br>
<tt>&nbsp; void </tt><tt>MarkAsStatic</tt><tt>() { IsStatic=true; }</tt><br>
<tt>};</tt><br>
</blockquote>
<tt>
</tt><br>
<tt>And then everywhere in the code where an object is allocated
statically, a line must be added: object.MarkAsStatic();<br>
<br>
Is that correct? Aren't there any simpler alternatives?<br>
<br>
Or is there something wrong with my the design of this ref-counting
system?<br>
<br>
Cheers,<br>
<br>
Jo<br>
<br>
<br>
</tt>Salt_Peter wrote:<br>
<blockquote type="cite"
cite="(e-mail address removed)">
<pre wrap="">Jo wrote:
</pre>
<blockquote type="cite">
<pre wrap="">Hi,

How can i differentiate between static and dynamic allocated objects?

For example:

void SomeFunction1() {

CObject *objectp = new CObject;
CObject object;

SomeFunction2(objectp,&amp;object);
}

void SomeFunction2(CObject *op1,CObject *op2) {

// now how do i know whether op1/op2 was statically or dynamically
allocated?
// and thus whether i may call a 'delete' on it?

}

Thanks,

Jo
</pre>
</blockquote>
<pre wrap=""><!---->
Thats your responsability. In the same breath that the CObject labelled
as object is a local variable in SomeFunction1(). Remember: new removes
all responsability the compiler has to destroy / recover that
allocation. You've dissmissed the compiler's duties.

There is a lot you can do to help. One might be to use a smart pointer
instead of new/delete. Another is to not allocate as its not required
in the example given. Properly naming your objects goes a long way too.
And in the case you do choose to new and delete, don't give one
function or class the responsability to new and another function or
class the responsabilty to delete (distribute allocations as a
responsability to one entity only - that is a sacred law, it can't be
over-emphasized).

void SomeFunction1() {
CObject *p_object = new CObject;
CObject object;

SomeFunction2( *p_object, object );

delete p_object;
}

void SomeFunction2( CObject&amp; op1, CObject&amp; op2 ) {
// now how do i know whether...
// answer: its not my responsability
}

pass arguements by reference, not pointers
and pass by const reference if you aren't modifying the args

Theres more, you can load CObjects in a std::vector. Assuming that
CObject is copyable and assignable.
#include &lt;vector&gt;
std::vector&lt; CObject &gt; vobj(1000000); // one million default CObjects

</pre>
</blockquote>
</body>
</html>

--------------020901060602050002080207--

Please...
don't top post. Your responses should go inline so that the discussion
can be followed by others.
Also, post in plain text, not html.
 
J

Jo

Hi Peter,

Thanks for pointing to the boost shared_ptr.

But that still doesn't solve it as that is only for dynamically
allocated objects, i.e. allocated via 'new'.

But i want a smart ref-count system where i can just mix dynamic and
static objects, and that the ref-count system knows if the ref-count
gets 0, wether it then has to 'delete' the object, or just leave it as
it is, because it gets deleted automatically when it gets out of scope.

A concrete example: i want to work with gui-objects like buttons,
sliders, scrollbars, treelists etc...
All these gui-objects are (directly or indirectly) inherited from
CObject, which is a very base class for almost all objects, also other
non-gui objects.

But sometimes a button is created via 'new', other times a button is
allocated on the stack. But it are all instances from the same class.
And ref-countable. But of course the button created on the stack may not
be deleted when its ref-count gets 0.

Hope i explained things well.

Anyway, i can conclude from the answers you, Thomas and Mike gave
(thanks guys) that there is no instant / simple solution for the problem
i posed, i.e. a proper ref-counting system that can
handle->differentiate between both dynamic and static allocated objects.

There always will be necessary specific code that tells about the
difference "static/dynamic", whichever mecanism is used to make the
differentiation.

So be it. A shortcoming of c++ imho, which is a great language though.
(i heard java doesn't have this problem, true?)

Anyway: My best whishes for 2007!!!

Cheers,

Jo

PS: Peter, you wrote "don't top post". What do you mean by that? Should
i put my reply "under" the original posts?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,999
Latest member
MakersCBDGummiesReview

Latest Threads

Top