🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

5 total messages Started by M.P. Kirby Fri, 20 Nov 1992 19:18
Finding memory leaks
#3
Author: M.P. Kirby
Date: Fri, 20 Nov 1992 19:18
33 lines
2025 bytes
In C I used to use a memory leak finder that would help me find
my memory leaks.  I basically created a #define for malloc that redefined
it to do:

#define malloc(size) (my_malloc(__FILE__,__LINE__,size)

This allowed me to maintain a list of all my memory allocations.  I would
redefine free to be my_free to mark the element on the list as "freed."
This allowed me to check to see what memory was outstanding at 
different points in the program. (and at the end).  I would then be
able to find out that a block of 300 k was allocated in file "stuff.c" at
line 53.  This proved useful during the debuging stage.

I would like to do the same kind of thing in C++.  Unfortunately, it
seems that new is not as easy to #define over as malloc.  I thought
(briefly) that I could do something like #define new new(__LINE__,__FILE__) 
 and then overload the new operator, but this causes a recursive macro.

Creating something that calls my_new doesn't work either.  Apparently the
sytanx surround the new operator is special.

Is there anyway to do what I am trying to accomplish?  

Actually, What I would really want is a stack dump at every memory allocation.
This way I would not only know that a block was allocated at a certain
line number and in a file, but it was ordered by these people.  But I'm
willing to take the easy way out.  Just knowing that I have a memory
leak and where it is occuring is good enough.


Mike Kirby
mpk9172@ultb.isc.rit.edu
Rochester Institute of Technology
Re: Finding memory leaks
#4
Author: Vidar Bosnes
Date: Sat, 21 Nov 1992 14:53
19 lines
1508 bytes
Mike Kirby (mpk9172@ultb.isc.rit.edu) writes:
>   I would like to do the same kind of thing in C++.  Unfortunately, it
>   seems that new is not as easy to #define over as malloc.  I thought
>   (briefly) that I could do something like #define new new(__LINE__,__FILE__) 
>   and then overload the new operator, but this causes a recursive macro.

There should be no problem in using the macro you suggested. The ARM
(chap 16.3.3), Preprocessing; rescanning and further replacement, reads:

   After all parameters in the replacement list have been replaced, the
   resulting list is rescanned for more macros to replace. If the name
   of the macro being replaced is found during this scan or during
   subsequent rescanning, it is not replaced.

Thus, there is no recursion involved. I have used this technique
successfully with g++ and dec-cxx. If you use g++, note that this
compiler uses non-standard syntax for the call to the overloaded
new-operator (curly braces instead of parentheses).
 
Re: Finding memory leaks
#5
Author: Steve Clamage
Date: Sun, 22 Nov 1992 18:19
30 lines
1955 bytes
mpk9172@ultb.isc.rit.edu (M.P. Kirby) writes:

>In C I used to use a memory leak finder that would help me find
>my memory leaks.  I basically created a #define for malloc that redefined
>it ...

>I would like to do the same kind of thing in C++.  Unfortunately, it
>seems that new is not as easy to #define over as malloc.  I thought
>(briefly) that I could do something like #define new new(__LINE__,__FILE__) 
> and then overload the new operator, but this causes a recursive macro.

There have been two answers to this question that completely missed
the point.  You do NOT want to replace "new" with a macro.  "new" is
a keyword which causes constructors to be called, and memory to be
allocated via the function "operator new()".  If you replace the "new"
keyword with a macro, you destroy the semantics of most programs.

You are allowed in C++ to replace "operator new()" and "operator delete()"
with your own versions.  Since these are the functions which actually do
the memory allocation, you can get any effect you want by replacing them.
(If you replace one, you should replace both, to ensure compatibility.)
You don't even have to recompile any code -- just re-link your program.
The ARM and Stroustrup 2 explain how to do this, apart from other books
and many magazine articles which also cover the subject.  It takes a bit
of explaining to cover all the subtle points which you have to consider,
so I prefer not to present just a simplistic answer here.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16
Re: Finding memory leaks
#6
Author: Fergus James HENDERSON
Date: Mon, 23 Nov 1992 02:47
42 lines
2682 bytes
steve@taumet.com (Steve Clamage) writes:

>mpk9172@ultb.isc.rit.edu (M.P. Kirby) writes:
>
>>In C I used to use a memory leak finder that would help me find
>>my memory leaks.  I basically created a #define for malloc that redefined
>>it ...
>
>>I would like to do the same kind of thing in C++.  Unfortunately, it
>>seems that new is not as easy to #define over as malloc.  I thought
>>(briefly) that I could do something like #define new new(__LINE__,__FILE__) 
>> and then overload the new operator, but this causes a recursive macro.
>
>There have been two answers to this question that completely missed
>the point.  You do NOT want to replace "new" with a macro.  "new" is
>a keyword which causes constructors to be called, and memory to be
>allocated via the function "operator new()".  If you replace the "new"
>keyword with a macro, you destroy the semantics of most programs.

Unfortunately, we DO want to replace "new" with a macro, so that we can
get __LINE__ and __FILE__. Redefining operator new() is not sufficient, because
__LINE__ inside operator new() refers to the line where operator new() was
redefined, not the line where new was invoked.

The problem is not that "new" causes constructors to be called: we can solve
that by invoking "new" from within the macro definition. Neither is the
problem with recursive macros: as noted previously, they are quite OK.
The problem is that the macro preprocessor is not capable of replacing
all uses of keyword "new" which will cause calls to "::operator new()"
without also affecting other uses of the "new" keyword.
(Vector new and delete might also cause some other problems.)

The only way that I can see of solving the problem is to write a preprocessor
which properly parses the source code, and then does the desired replacements.
I don't see how it could be done using just the simple textual substitution
provided by the C preprocessor.

-- 
Fergus Henderson             fjh@munta.cs.mu.OZ.AU      
This .signature virus is a self-referential statement that is true - but 
you will only be able to consistently believe it if you copy it to your own
.signature file!
Re: Finding memory leaks
#7
Author: Steve Clamage
Date: Mon, 23 Nov 1992 21:04
49 lines
2459 bytes
fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON) writes:

>steve@taumet.com (Steve Clamage) writes:

>>mpk9172@ultb.isc.rit.edu (M.P. Kirby) writes:
>>
>>>In C I used to use a memory leak finder that would help me find
>>>my memory leaks.  I basically created a #define for malloc that redefined
>>>it ...

>>>I would like to do the same kind of thing in C++...

>>You do NOT want to replace "new" with a macro.  "new" is
>>a keyword which causes constructors to be called, and memory to be
>>allocated via the function "operator new()".  If you replace the "new"
>>keyword with a macro, you destroy the semantics of most programs.

>Unfortunately, we DO want to replace "new" with a macro, so that we can
>get __LINE__ and __FILE__. Redefining operator new() is not sufficient, because
>__LINE__ inside operator new() refers to the line where operator new() was
>redefined, not the line where new was invoked. ...

>The only way that I can see of solving the problem is to write a preprocessor
>which properly parses the source code, and then does the desired replacements.
>I don't see how it could be done using just the simple textual substitution
>provided by the C preprocessor.

If you don't mind modifying the source code, you can use placement syntax.
For example, instead of
        T* p = new T;
you would use
        T* p = new (__FILE__, __LINE__) T;
The result would be a call to
        operator new(size_t size, char* file, int line)
which would be your specialized allocation function.

You could use a macro to make this less tedious:
	#define my_new(x)	new (__FILE__, __LINE__) x
	...
	T* p = my_new(T);
 
Then write your own operator delete.  You have to be aware that there may
be calls to ordinary operator new from the library or other code.  Your
operator delete has to be able to cope with both, since there can be
only one (global) operator delete in the system.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads