|
|
User login
Feeds |
overload 'new' and 'delete'?
|
|||||
| Wed, 2004-12-08 08:52 | |
|
Hi, Can I overload the 'new' and 'delete' operators in Symbian C++? Bye. --Mayur. |
|
Forum posts: 192
try and then tell us
Forum posts: 404
illegal operator overloading when I try overlaoding 'new'.
>>TAny* operator new(TState1 /*aState*/);
Any idea why this error?
Bye.
--Mayur.
http://symbiangeek.blogspot.com
Forum posts: 23
Forum posts: 404
****************************************************
inline TAny* CBase::operator new(TUint aSize, TAny* aBase)
{
Mem::FillZ(aBase,aSize);
return(aBase);
}
inline TAny* CBase::operator new(TUint aSize, TLeave)
{
return newL(aSize);
}
****************************************************
And This is my overloaded 'new':
************************************************
declaration : TAny* operator new(TInt size);
definition :
TAny* TMyHeapWalkClass::operator new(TInt size)
{
return;// empty
}
************************************************
have kept it empty on purpose.
So where is the clash?
Pls help.
--Mayur.
http://symbiangeek.blogspot.com
Forum posts: 1379
class CMyClass
{
public:
inline TAny* operator new(TUint aSize) { return 0; };
CMyClass() {};
};
Note, you must use TUint, not TInt - or you will get error:
error C2821: first formal parameter to 'operator new' must be 'unsigned int'
At least in a decient compiler/debugger
If your trying to redefine the global operaotrs, you wont be able too because you will get errors about multiple defined symbols:
error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in Helloworld.obj
Since it doesn't know which one you mean.
If your trying to do a heap checker type thing, you could use a parameter in the same way new (ELeave) works:
enum TCheckHeap
{
ECheckHeap
};
inline TAny* operator new(TUint aSize, TCheckHeap) { return 0; };
class CMyClass
{
public:
CMyClass() {};
};
// do the example
LOCAL_C void doExampleL()
{
CMyClass* n = new CMyClass; // will call global new
n = new (ECheckHeap) CMyClass; // will call our new overide
}
didster
Forum posts: 404
Your answer just proves why you are the 'Forum Expert'
Was breaking head over this for full 5 hours , finally solved it.
Thanks again for the answer.
--Mayur.
http://symbiangeek.blogspot.com
Forum posts: 1379
didster
Forum posts: 404
overloaded new?
I want the user to be able to select if he wants my new or the
one provided by Symbian.
Also one more thing ,now the code compiles , but when i debug
the code does not transfer to my new it goes to the old new itself.
Well I want to replace the Symbian's new , so for every new called in code
my new operator function gets executed.
How can I change that?
Thanks.
--Mayur.
http://symbiangeek.blogspot.com
Forum posts: 1379
enum TCheckHeap
{
ECheckHeap
};
inline TAny* operator new(TUint aSize, TCheckHeap) { return 0; };
Calling the old new will be a simple case of calling new (ELeave) or just new.
If you have declared it as a class memeber, calling the old new will be as simple as:
::new CFish;
i.e. explicatly scope it.
As for how to replace the new calls without code changes, well its tricky. As I said, just reoverloading the new operator wont work because you will get link errors about multiple defined symbols - new (TUint...) will defined both in your class, and in symbians libs (euser.lib i think). There are two ways I can think of doing it:
inline TAny* operator new(TUint nSize, char* lpszFileName, int nLine) { return 0; };
#ifdef _DEBUG
#define new(a) new(__FILE__, __LINE__)
#endif
class CMyClass
{
public:
CMyClass() {};
};
// do the example
LOCAL_C void doExampleL()
{
CMyClass* n = new (ELeave) CMyClass;
}
This approach will call the overloaded new if _DEBUG is defined, and the old one otherwise. The problem with this is it will only work for new (ELeave) - and you can't do:
#define new new(__FILE__, __LINE__)
Because of macro rubbish. Calling the original new in this case is easy.
The second is like this:
enum TCheckHeap
{
ECheckHeap
};
class C
{
};
#ifdef _DEBUG
#define ELeave ECheckHeap
#endif
inline TAny* operator new(TUint aSize, TCheckHeap) { return new ((TLeave)ELeave) C; };
class CMyClass
{
public:
CMyClass() {};
};
// do the example
LOCAL_C void doExampleL()
{
CMyClass* n = new (ELeave) CMyClass;
}
Here you redefine ELeave to be ECheckHeap - so new (ELeave) actually calls new (ECheckHeap). Then, to call the original new, you cast the ELeave to a TLeave explicatly.
I would go for the second method. Hope that helps.
didster
Forum posts: 404
I overloaded the global 'new' and was able to get it called in classes not derived from CBase,but otherwise its difficult to replace the CBase::new
with our 'new' and also not recommended as its side effects are not clear.
Anyway I have stopped breaking my head over this and trying out
something else.
Thanks didster for u r wonderful answers.
Lets hope somebody can come up with a solution to overload CBase::new safely.
Bye.
--Mayur.
http://symbiangeek.blogspot.com
Forum posts: 1379
Try this:
namespace Ta
{
class CBase : public ::CBase
{
public:
TAny* operator new(TUint aSize, TLeave);
};
class CBlah : public CBase
{
};
TAny* CBase::operator new(TUint aSize, TLeave) { return ::new (ELeave) CBlah; }
void Test()
{
CBlah* n = new (ELeave) CBlah;
}
}
// do the example
LOCAL_C void doExampleL()
{
Ta::Test();
}
Here, we redefine CBase in our own namespace, deriving from the global CBase. You can the overload new in there. Then, in you new, you call the old global new.
You could then create some kind of header that defined CBase in the Ta namespace only if _DEBUG was defined, and have something like:
#ifdef _DEBUG
#define HEAPCHECKNSOPEN namespace Ta {
#define HEAPCHECKNSCLOSE }
#else
#define HEAPCHECKNSOPEN
#define HEAPCHECKNSCLOSE
#endif
HEAPCHECKNSOPEN
..
..
// Your code goes here
..
..
HEAPCHECKNSCLOSE
This would put your code in the Ts namespace (and hence use your own CBase) only if _DEBUG was defined.
Hope it helps.
didster
Forum posts: 404
Man u r answers.. ::fainted
::recovered now
I will just let u know my idea.
According to my knowledge , you cannot profile an application in Symbian
(unless u have invented something already
So my idea was to replace the system 'new' and 'delete' with my 'new'
and 'delete' which will log each user done memory allocation and
deallocation and generate a log file at the end of each app execution
detailing all the allocation and deallocations done.
This will be a way of detecting memory leaks quite easily and will also help
in profiling apps, abt how much memory allocation is done and all that.
I'd thought that it was simple , but now have realised that it would
have great implications beyond our control.
What do u think is this idea implementable or am I a nut coz there already exists such a thing??
Hope to hear some words from u instead of u r code
Bye.
--Mayur.
http://symbiangeek.blogspot.com
Forum posts: 1379
We use a tool called Bulleseye for code coverage, and that works on target. I'm not sure if it does profiling though.
Again, for memory leak testing (and also profiling in a way) we use an internal tool which replaces the system RHeap classes with one of it's own, loging each allocation etc.
I'd love to share it, but (I belive, ill check) it's not public domain stuff, and certinally isn't my copyright
If you are serious about doing it, you may be better going for the same approach. Given you don't have the code for euser.dll, you would need to create a stub DLL for EUser, forwaring all calls on to the origanl EUser.dll, apart from RHeap Alloc/Free, which you could forward on, then log the results.
A quick run of dumpbin /EXPORTS euser.lib reveals you would have 1654 stub functions to write
didster
Forum posts: 404
The link you sent did not work.So pls do send me the right link also
so that I can check the tool.
I am considering doing this thing , but from where can I get the complete list of functions present in euser.lib?
Can i assume that only e32std.h has all the functions are some other
header also goes into making the euser lib?
Thanks and Bye.
--Mayur.
http://symbiangeek.blogspot.com
Forum posts: 1379
For the full list:
dumpbin /EXPORTS euser.lib
didster