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

Macro needed

Hi List,
I am overloading new and delete globally for memory leak detection.

void* operator new(std::size_t s, const char * file , int inLine) ;
->case1
void* operator new[](std::size_t s, const char * file , int inLine);
->case 2

I implement the above two functions using malloc. Now to replace all
occurances of
standard new with my above new operator I use the below macro.
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW

This works for first case.
My question is can I define a Macro in a similar way for second case
also?
if so, how?
if not, any work around to replace all occurances of operator new[]
with my operator?

---
Thanks,
Yogesh Kini

Jan 10 '06 #1
4 2318
Yogesh wrote:
I am overloading new and delete globally for memory leak detection.

void* operator new(std::size_t s, const char * file , int inLine) ;
->case1
void* operator new[](std::size_t s, const char * file , int inLine);
->case 2

I implement the above two functions using malloc. Now to replace all
occurances of
standard new with my above new operator I use the below macro.
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW

This works for first case.
My question is can I define a Macro in a similar way for second case
also?
Doesn't it work for the second case as well?
if so, how?
if not, any work around to replace all occurances of operator new[]
with my operator?


Uh... I am sorry, I probably don't understand the problem. If you
have

int * pi = new int(666);

you now get

int * pi = new("somefile.cc", 42) int(666);

, right? So, if you have to allocate an array,

int * parr = new int[666];

would it just as well be

int * parr = new("somefile.cc", 42) int[666];

??? What's different about 'new[]'? Or were you just afraid to try?

V
Jan 10 '06 #2
Yogesh wrote:
Hi List,
I am overloading new and delete globally for memory leak detection.

void* operator new(std::size_t s, const char * file , int inLine) ;
->case1
void* operator new[](std::size_t s, const char * file , int inLine);
->case 2

I implement the above two functions using malloc. Now to replace all
occurances of
standard new with my above new operator I use the below macro.
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW

This works for first case.
My question is can I define a Macro in a similar way for second case
also?
if so, how?
if not, any work around to replace all occurances of operator new[]
with my operator?

---
Thanks,
Yogesh Kini


If we ignore the bigger problem, I think your #defines would work for
both new and new[] since you'd invoke it like this:

int *ptr = new int(42);
int *array = new int[ 100 ];

With your macros, these would become

int *ptr = new("MyFile.cpp", 10) int(42);
int *array = new("MyFile.cpp", 11) int[ 100 ];

However, let me suggest that your approach of using __FILE__ and
__LINE__ won't work. See this recent discussion for details:

http://groups.google.com/group/comp....011b4e2c8e4be6

Consider using an existing library for your platform to look for leaks,
rather than writing your own. (Google for them.) Also, the thorough use
of smart pointers (e.g., std::auto_ptr, boost::scoped_ptr, and
boost::shared_ptr) virtually eliminates the possibility of memory
leaks. Consider using such practices.

Cheers! --M

Jan 10 '06 #3
Hi ,
Thanks for prompt reply.
I was not aware that though "new" and "new[]" are different operators,
they are
translated in the same(similar) way by the compiler.
Consider using an existing library for your platform to look for leaks,
rather than writing your own. (Google for them.) Also, the thorough use
of smart pointers (e.g., std::auto_ptr, boost::scoped_ptr, and
boost::shared_ptr) virtually eliminates the possibility of memory
leaks. Consider using such practices.
I am looking into existing code, so replacing normal pointers with
std::auto_ptr,
boost::scoped_ptr is tedious job. Also I felt it would be a good
experience to do
it myself, than using a existing tool.

However, let me suggest that your approach of using __FILE__ and
__LINE__ won't work. See this recent discussion for details:


Dont know, why you say that. Please look at the code below. It seems to
work fine.
Mac OSX 10.4.2, gcc 4.0.1(Xcode)

Let me know if I am doing something wrong.
I call void "PrintMemoryDump()" at application Shutdown.

---------------------------------MemoryTest.h(Begin)--------------------------------------------------

#ifndef _MEMORY_TEST_H_
#define _MEMORY_TEST_H_

#include <new>
#include <stdio.h>
#include <stdlib.h>

void* operator new(std::size_t s, const char * file , int inLine) ;
void operator delete(void*) throw();

void* operator new[](std::size_t s, const char * file , int inLine);
void operator delete[](void*) throw();

void PrintMemoryDump();

#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW

#endif

---------------------------------MemoryTest.h(End)--------------------------------------------------

---------------------------------MemoryTest.cpp(Begin)--------------------------------------------------
#include "MemoryTest.h"
#ifdef DEBUG_NEW
#define DEBUG_NEW new
#endif

struct tMemoryBlock
{
char _file[256];
int _lineNumber, _numBytes;
void * _pointer;
bool _deleted;
tMemoryBlock * next;
};

tMemoryBlock* head = NULL;

void AddBlock(tMemoryBlock ** inBlock)
{
if(head == NULL)
{
head = *inBlock;
return;
}
tMemoryBlock * ptr = head;
while(ptr ->next != NULL)
{
ptr = ptr->next;
}
ptr ->next = *inBlock;
}

void RemoveBlock(void * inptr)
{
if(head == NULL) return;
tMemoryBlock * ptr = head;
while(ptr != NULL)
{
if(ptr->_pointer == inptr)
{
ptr->_deleted = true;
}
ptr = ptr->next;
}
}

void PrintMemoryDump()
{
tMemoryBlock * ptr = head;
while(ptr != NULL)
{
if(ptr->_deleted == false)
{
fprintf(stderr, "**MEM LEAK** %s %d\n",ptr->_file,ptr->_lineNumber);
}
ptr =ptr->next;
}
ptr = head->next; tMemoryBlock * dptr= head;

while(ptr != NULL)
{
free(dptr);
dptr = ptr;
ptr = ptr->next;
}
}

void* operator new(std::size_t s, const char * file , int inLine)
{
void *ptr = (void *)malloc(s);
tMemoryBlock * t = (tMemoryBlock*)malloc(sizeof(tMemoryBlock));
strcpy(t->_file, file);
t->_lineNumber = inLine;
t->_deleted = false;
t->_numBytes = s;
t->next = NULL;
t->_pointer = ptr;

AddBlock(&t);

return(ptr);
}

void operator delete(void* p) throw()
{
RemoveBlock(p);
free(p);
}

void* operator new[](std::size_t s, const char * file , int inLine)
{

void *ptr = (void *)malloc(s);
tMemoryBlock * t = (tMemoryBlock*)malloc(sizeof(tMemoryBlock));
strcpy(t->_file, file);
t->_lineNumber = inLine;
t->_deleted = false;
t->_numBytes = s;
t->next = NULL;
t->_pointer = ptr;

AddBlock(&t);
return(ptr);
}

void operator delete[](void*p) throw()
{
RemoveBlock(p);
free(p);
}

#define new DEBUG_NEW
#define DEBUG_NEW new(__FILE__, __LINE__)
---------------------------------MemoryTest.cpp(End)--------------------------------------------------

Jan 11 '06 #4
Yogesh wrote:
Consider using an existing library for your platform to look for leaks,
rather than writing your own. (Google for them.) Also, the thorough use
of smart pointers (e.g., std::auto_ptr, boost::scoped_ptr, and
boost::shared_ptr) virtually eliminates the possibility of memory
leaks. Consider using such practices.


I am looking into existing code, so replacing normal pointers with
std::auto_ptr,
boost::scoped_ptr is tedious job. Also I felt it would be a good
experience to do
it myself, than using a existing tool.


It would likely be a good learning exercise, and I commend it to you
for your edification. However, if this is for production code, I would
suggest using an existing library since there are can be quite a few
subtleties involved. (For similar reasons, Bjarne Stroustrup recommends
in TC++PL 6.2.6.2 that anyone wishing to implement a garbage collector
except as an educational exercise should get one that has already been
written and tested.)
However, let me suggest that your approach of using __FILE__ and
__LINE__ won't work. See this recent discussion for details:


Dont know, why you say that. Please look at the code below. It seems to
work fine.
Mac OSX 10.4.2, gcc 4.0.1(Xcode)

Let me know if I am doing something wrong.
I call void "PrintMemoryDump()" at application Shutdown.

---------------------------------MemoryTest.h(Begin)--------------------------------------------------

#ifndef _MEMORY_TEST_H_
#define _MEMORY_TEST_H_

#include <new>
#include <stdio.h>
#include <stdlib.h>

void* operator new(std::size_t s, const char * file , int inLine) ;
void operator delete(void*) throw();

void* operator new[](std::size_t s, const char * file , int inLine);
void operator delete[](void*) throw();

void PrintMemoryDump();

#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW

#endif

---------------------------------MemoryTest.h(End)--------------------------------------------------


[code snipped]

One of the subtleties that I have in mind is that, when new fails (e.g.
if a constructor throws an exception), the compiler implicitly looks
for a corresponding delete operator with a similar signature to the
new, but you have not provided such an operator, which means you would
have a very tricky memory leak. See this FAQ:

http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14

which describes what happens behind the scenes when you call new. Note
particularly its "Problem #1". (The FAQ discusses placement new, which
is similar to your "new with parameter" usage here.)

In any case, I was assuming that you were using the filename/line to be
the block lookup key, which you are not. So you've already avoided one
danger present in the previously cited thread.

BTW, I only looked cursorily at your code, but I did notice that
AddBlock() doesn't need a double pointer passed in.

Cheers! --M

Jan 11 '06 #5

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

Similar topics

25
by: Andrew Dalke | last post by:
Here's a proposed Q&A for the FAQ based on a couple recent threads. Appropriate comments appreciated X.Y: Why doesn't Python have macros like in Lisp or Scheme? Before answering that, a...
0
by: Donald 'Paddy' McCarthy | last post by:
So, for those that don't actively not-want a Python macro facility. If we are to have it what should it do? 1) Macro definitions should allow Doc strings. 2) There should be a separate statement...
0
by: Newbillian | last post by:
After converting Access 97 databases to 2003 this error msg shows up after a line about not being able to save the record because a related record is needed in another table. The complete msg is: ...
6
by: MLH | last post by:
Did A97, perchance, do away with the need for an AutoExec macro to initiate an autoexec sequence for databases? Or, must we still suffer with that hideous macro?
17
by: sounak | last post by:
How could we get a macro name from a macro value such that in a header file #define a 100 #define b 200 now the source file will be such that the user gives 100 then the value is outputted as...
6
by: Takeadoe | last post by:
Dear NG, Can someone assist me with writing the little code that is needed to run an update table query each time the database is opened? From what I've been able to glean from this group, the...
3
by: swb76 | last post by:
Hi, I have 6 queries in Access that run great. They need to be run in sequence with the first 5 queries writing to tables and the sixth one pops up the final results in datasheet view. Now, how...
19
by: Tor Rustad | last post by:
I'm implementing a parser, where there is a lot of different data elements defined. Now instead of hand-coding X defines, and the massive number of lines needed for table initialization, I decided...
3
MMcCarthy
by: MMcCarthy | last post by:
Although some users find Macros simple and easy to use, there are some major limitations to using them. Although you can use macros to perform tasks, there is limited control on when and how those...
33
by: Peng Yu | last post by:
Hi, __PRETTY_FUNCTION__ is a macro that gives function name, etc. I'm wondering if there is a macro to get the class name inside a member function. Thanks, Peng
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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?

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.