473,395 Members | 1,653 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,395 software developers and data experts.

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

Nov 28 '05 #1
10 1810
Gr*****@nospam.com wrote:
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.8) 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.

Nov 28 '05 #2
> 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
Nov 28 '05 #3
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

Nov 28 '05 #4
"Gr*****@nospam.com" <Gr**********@gmail.com> wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com
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.
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
Nov 28 '05 #5
Gr*****@nospam.com wrote:
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
Nov 28 '05 #6
Gr*****@nospam.com <Gr**********@gmail.com> wrote:
| 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.

| 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?

| 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
Nov 28 '05 #7
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

Nov 28 '05 #8
Gr*****@nospam.com wrote:
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.

Nov 28 '05 #9
Rolf Magnus wrote:
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).

Nov 28 '05 #10
> 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

Nov 29 '05 #11

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

Similar topics

11
by: Eitan Michaelson | last post by:
Hi, Can any one tell me what's wrong with this code? It leaks (acceding to bound checker), when it attempts to reallocate memory. The code is not pure C, but with minor adjustments any C...
32
by: John | last post by:
Hi all: When I run my code, I find that the memory that the code uses keeps increasing. I have a PC with 2G RAM running Debian linux. The code consumes 1.5G memory by the time it finishes...
7
by: Ethan | last post by:
Hi, I have a class defined as a "Singleton" (Design Pattern). The codes are attached below. My questions are: 1. Does it has mem leak? If no, when did the destructor called? If yes, how can I...
3
by: Giovanni Boschi | last post by:
We have found a memory leak when using a COM library with a C# application. The leak appears only if the C# application is compiled with the /optimize flag. It goes away when the C# application is...
23
by: James | last post by:
The following code will create memory leaks!!! using System; using System.Diagnostics; using System.Data; using System.Data.SqlClient; namespace MemoryLeak
7
by: Fernando Barsoba | last post by:
Hi, After following the advice received in this list, I have isolated the memory leak problem I am having. I am also using MEMWATCH and I think it is working properly. The program does some...
4
by: mast2as | last post by:
Hi guys I wrote a short program to test a Tree class... I plan to use it a lot in my application so thought I would do a memory leak check before I start using it. The code seems good to me in a...
8
by: vidya.bhagwath | last post by:
Hello Experts, I am using std::string object as a member variable in one of the my class. The same class member function operates on the std::string object and it appends some string to that...
17
by: Mike | last post by:
Hello, I have following existing code. And there is memory leak. Anyone know how to get ride of it? function foo has been used in thousands places, the signature is not allowed to change. ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
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...

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.