 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Grahamo@nospam.com Guest
|
Posted: Mon Nov 28, 2005 11:09 am Post subject: leak and void* |
|
|
Hi,
Question relating to pointers, void* and destructors.
assuming I have code like this;
int main(int argc, char** argv)
{
X* x = new X();
void* tmp = x;
x = 0;
delete tmp;
return 0;
}
Can anybody tell me definitively that the above code leaks memory. I
mean I'm calling delete on the tmp pointer (type void*) however the
destructor isn't being called. I *definitely* have a leak on my hands
here, don't i. The reason I'm asking is cos the tool I'm evaluating for
leak analysis is not reporting anything for the above code. I see that
the X destructor is NOT called however it's still not reporting leaks
to me.
Am I correct in thinking this is a leak, aren't I. In order for it not
to leak, I would need to declare tmp thus;
X* tmp = x;
delete tmp;
That way the correct destructor will be called. Using a void* as in the
first scenario is a leak, correct?
thanks
g
|
|
| Back to top |
|
 |
Neelesh Bodas Guest
|
Posted: Mon Nov 28, 2005 11:23 am Post subject: Re: leak and void* |
|
|
[email]Grahamo (AT) nospam (DOT) com[/email] wrote:
| Quote: | Hi,
Question relating to pointers, void* and destructors.
assuming I have code like this;
int main(int argc, char** argv)
{
X* x = new X();
void* tmp = x;
x = 0;
delete tmp;
return 0;
}
|
Deleting a void pointer has _undefined_ behaviour .
Quoting 5.3.5p2
In the first alternative (delete object), the value of the operand of
delete shall be a pointer to a nonarray object or a pointer to a
subobject (1. representing a base class of such an object (clause
10). If not, the behavior is undefined. In the second alternative
(delete array), the value of the operand of delete shall be the pointer
value which resulted from a previous array newexpression.IIf not, the
behavior is undefined.
since it is an undefined behaviour, it might or might not leak memory
or might even overwrite the entire memory. Basically writing such a
code is a serious error.
|
|
| Back to top |
|
 |
Sumedha Swamy Guest
|
Posted: Mon Nov 28, 2005 11:24 am Post subject: Re: leak and void* |
|
|
| Quote: | assuming I have code like this;
int main(int argc, char** argv)
{
X* x = new X();
void* tmp = x;
x = 0;
delete tmp;
return 0;
}
Can anybody tell me definitively that the above code leaks memory.
|
Hi,
Deleting `void*' is undefined.
Also, valgrind reports a memory leak here.
--Sumedha Swamy
|
|
| Back to top |
|
 |
Grahamo@nospam.com Guest
|
Posted: Mon Nov 28, 2005 11:37 am Post subject: Re: leak and void* |
|
|
Validator from software verify does not report a leak for me here...
that's what I'm after. I've only installed the tool 2 days ago, it
looks good but this is annoying me. I'm onto their support to see what
they have to say for themselves.
I think borland (version 6 cpp builder) is doing something weird (it's
allowed to anything it wants really as we're in "undefined behaviour"
territory as you pointed out). The memory consumption isn't going thru
the roof (stays static/flat) when the above allocation is put in a fat
while 1 loop. i.e.
while (1)
{
X* x = new X();
void* tmp = x;
x = 0;
delete tmp;
}
When I monitor this process the memory consumption stays flat, however
X::~X() is NEVER invoked. Is it possible for the compiler to reclaim
the memory without invoking the dtor? I mean, it's allowed to do
*anything* it wants when we get into undefined behaviour. Could that
be why I see no increase in process size. i.e. Borland is reclaiming
the memory but doing it HIS way instead of calling the dtor. Or is that
nonsense and there's another perfectly reasonably explanation for the
behaviour I'm seeing.
thanks
G
|
|
| Back to top |
|
 |
John Carson Guest
|
Posted: Mon Nov 28, 2005 11:38 am Post subject: Re: leak and void* |
|
|
"Grahamo (AT) nospam (DOT) com" <GrahamJWalsh (AT) gmail (DOT) com> wrote
| Quote: | Hi,
Question relating to pointers, void* and destructors.
assuming I have code like this;
int main(int argc, char** argv)
{
X* x = new X();
void* tmp = x;
x = 0;
delete tmp;
return 0;
}
Can anybody tell me definitively that the above code leaks memory. I
mean I'm calling delete on the tmp pointer (type void*) however the
destructor isn't being called. I *definitely* have a leak on my hands
here, don't i. The reason I'm asking is cos the tool I'm evaluating
for leak analysis is not reporting anything for the above code. I see
that the X destructor is NOT called however it's still not reporting
leaks to me.
|
It is undefined behaviour. According to the C++ standard, anything can
happen.
| Quote: | Am I correct in thinking this is a leak, aren't I. In order for it not
to leak, I would need to declare tmp thus;
X* tmp = x;
delete tmp;
That way the correct destructor will be called. Using a void* as in
the first scenario is a leak, correct?
|
Whether or not the destructor runs is irrelevant to the question of whether
or not the memory storing the X object is freed. When working properly,
delete first calls the X destructor and then frees the memory storing the X
object. These are independent acts. The running of the destructor is only
relevant to memory leaks if the destructor frees memory in which some other
object is stored (usually an object that was allocated using new in the
constructor).
Like I said, the consequences of calling delete on a void * pointer are
undefined. It is a common result that the memory for the object is freed but
the destructor is not called --- but anything can happen.
You really shouldn't be thinking this way. Calling delete on a void* pointer
gives undefined behaviour so you shouldn't do it whatever your leak
detection program says and however your program behaves. Just don't do it.
End of story.
--
John Carson
|
|
| Back to top |
|
 |
n2xssvv g02gfr12930 Guest
|
Posted: Mon Nov 28, 2005 11:43 am Post subject: Re: leak and void* |
|
|
[email]Grahamo (AT) nospam (DOT) com[/email] wrote:
| Quote: | Hi,
Question relating to pointers, void* and destructors.
assuming I have code like this;
int main(int argc, char** argv)
{
X* x = new X();
void* tmp = x;
x = 0;
delete tmp;
return 0;
}
Can anybody tell me definitively that the above code leaks memory. I
mean I'm calling delete on the tmp pointer (type void*) however the
destructor isn't being called. I *definitely* have a leak on my hands
here, don't i. The reason I'm asking is cos the tool I'm evaluating for
leak analysis is not reporting anything for the above code. I see that
the X destructor is NOT called however it's still not reporting leaks
to me.
Am I correct in thinking this is a leak, aren't I. In order for it not
to leak, I would need to declare tmp thus;
X* tmp = x;
delete tmp;
That way the correct destructor will be called. Using a void* as in the
first scenario is a leak, correct?
thanks
g
|
Your right the code is definitely unsound!!!!
Apparently deleting a void pointer is undefined, but not calling the
destructor of X before freeing up the memory where it is stored is
definitely a potential problem. Quite simply if X has allocated memory
which would normally be freed up by the destructor of X, (which is never
called), then that memory is obviously leaked.
JB
|
|
| Back to top |
|
 |
roberth+news@ifi.uio.no Guest
|
Posted: Mon Nov 28, 2005 11:54 am Post subject: Re: leak and void* |
|
|
[email]Grahamo (AT) nospam (DOT) com[/email] <GrahamJWalsh (AT) gmail (DOT) com> wrote:
| Quote: | Question relating to pointers, void* and destructors.
assuming I have code like this;
int main(int argc, char** argv)
{
X* x = new X();
void* tmp = x;
x = 0;
delete tmp;
return 0;
}
Can anybody tell me definitively that the above code leaks memory. I
|
No, we can't tell you. You have undefined behaviour:
C++ §3.5.3.3
«[...] if the static type of the operand is different from its dynamic
type, the static type shall be a base class of the operand's dynamic
type and the static type shall have a virtual destructor or the
behaviour is undefined. [...]»
No object has type void, and void is not a base class of any class.
| Quote: | mean I'm calling delete on the tmp pointer (type void*) however the
destructor isn't being called. I *definitely* have a leak on my hands
here, don't i. The reason I'm asking is cos the tool I'm evaluating for
leak analysis is not reporting anything for the above code. I see that
the X destructor is NOT called however it's still not reporting leaks
to me.
|
You have undefined behaviour. Adding a trivial class X to your example,
I got this with gcc (both 3.4.4 and 4.0.2) when trying to compile:
$ g++ test.cc
test.cc: In function `int main(int, char**)':
test.cc:14: warning: deleting `void*' is undefined
Didn't your compiler issue any warning?
| Quote: | X* tmp = x;
delete tmp;
That way the correct destructor will be called. Using a void* as in the
first scenario is a leak, correct?
|
No, it's UB. Anything could happen.
--
Robert Bauck Hamar
|
|
| Back to top |
|
 |
Grahamo@nospam.com Guest
|
Posted: Mon Nov 28, 2005 12:09 pm Post subject: Re: leak and void* |
|
|
Hi,
"You really shouldn't be thinking this way. Calling delete on a void*
pointer
gives undefined behaviour so you shouldn't do it whatever your leak
detection program says and however your program behaves. Just don't do
it.
End of story. "
I agree with you now I have the replies from above. This is a test I'm
doing, not real code. I am trying to determine how this analysis tool
is working. When I call delete on the void* the memory associated with
the void* is being cleaned up however the destructor for the object it
points to is not being invoked. This explains the output in the tool
I'm using (it shows me no leak) and also why the process size isn't
growing. If I had allocated memory in the constructor I would have seen
a leak reported. All good. Thanks for the responses.
thanks
G
|
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Mon Nov 28, 2005 2:22 pm Post subject: Re: leak and void* |
|
|
[email]Grahamo (AT) nospam (DOT) com[/email] wrote:
| Quote: | Validator from software verify does not report a leak for me here...
that's what I'm after. I've only installed the tool 2 days ago, it
looks good but this is annoying me. I'm onto their support to see what
they have to say for themselves.
I think borland (version 6 cpp builder) is doing something weird (it's
allowed to anything it wants really as we're in "undefined behaviour"
territory as you pointed out). The memory consumption isn't going thru
the roof (stays static/flat) when the above allocation is put in a fat
while 1 loop. i.e.
while (1)
{
X* x = new X();
void* tmp = x;
x = 0;
delete tmp;
}
When I monitor this process the memory consumption stays flat, however
X::~X() is NEVER invoked. Is it possible for the compiler to reclaim
the memory without invoking the dtor? I mean, it's allowed to do
*anything* it wants when we get into undefined behaviour. Could that
be why I see no increase in process size. i.e. Borland is reclaiming
the memory but doing it HIS way instead of calling the dtor. Or is that
nonsense and there's another perfectly reasonably explanation for the
behaviour I'm seeing.
|
The deallocation of the memory and the execution of the destructor are two
distinct actions that are taken when the object gets destroyed. An
implementation's underlying memory manager might be able to give the
allocated memory back by just knowing the address. However, the destructor
can't be called, since on deletion of a pointer to void, the actual type
isn't known anymore. In this case, the object is handled as raw memory that
doesn't have a destructor.
In on an implementation that handles it like that, this means there is
actually only a potential resource leak. Only if the task of the object's
(or any of its members') destructor was to deallocate some resources, those
resources leak because no destructor is called.
|
|
| Back to top |
|
 |
Ron Natalie Guest
|
Posted: Mon Nov 28, 2005 6:28 pm Post subject: Re: leak and void* |
|
|
Rolf Magnus wrote:
| Quote: | The deallocation of the memory and the execution of the destructor are two
distinct actions that are taken when the object gets destroyed. An
implementation's underlying memory manager might be able to give the
allocated memory back by just knowing the address. However, the destructor
can't be called, since on deletion of a pointer to void, the actual type
isn't known anymore. In this case, the object is handled as raw memory that
doesn't have a destructor.
|
It's not just the destructor that's of issue. The proper deallocation
function might not be called (operator delete might have been overloaded
for that type).
|
|
| Back to top |
|
 |
Vladimir Guest
|
Posted: Tue Nov 29, 2005 12:22 am Post subject: Re: leak and void* |
|
|
| Quote: | int main(int argc, char** argv)
{
X* x = new X();
void* tmp = x;
x = 0;
delete tmp;
return 0;
}
Can anybody tell me definitively that the above code leaks memory. I
mean I'm calling delete on the tmp pointer (type void*) however the
destructor isn't being called. I *definitely* have a leak on my hands
here, don't i. The reason I'm asking is cos the tool I'm evaluating for
leak analysis is not reporting anything for the above code. I see that
the X destructor is NOT called however it's still not reporting leaks
to me.
|
So you are breaking type safety in catastrophic manner and fail
to accept that just because some obscure tool says it's ok?
The real problem is in relying on analysis tools which leads
to reduced quality and wrong design decisions. I'd better use
simple but powerful RAII mechanism than some artificial tool.
--
Vladimir
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|