![]() |
overloading global new/delete
hey, im trying to overload the global new and delete operators, im getting very strange allocations from malloc(...)
:
//Debug.hinstead of 10 new calls, there are 21??? :
clear; g++ -DMEM_DEBUG main.cpp -otest; ./testwhats wrong? :confused: |
Nothing's necessarily wrong. Standard containers dynamically allocate and deallocate memory, which might (or might not; it depends on implementation of the allocator) make use of global operator new and delete.
|
ah ok i see now! thanks for pointing that out! :)
but wouldnt there be an equal number of delete calls for every new call? |
Indeed there is a mistake here
Hi rwm,
You have come up with really a genuine doubt, which is hardly seen or detected. It took me so much long to identify the same. Indeed there is a problem with your code, but before that I would like to inform something regarding why you are getting such answer. The answer you are getting is dependent on compiler. The compiler like turboC may give you error for such code. Compiler like CC will give an immediate core dump / memory fault. And the compiler what you are using is giving you wrong output, which is more dangerous because you can't predict in big codes that something is really wrong. When I compiled in CC, it was giving mem fault from the beginning. So I commented eveything inside the main() (retaining the above function definitions of f(), new(), delete() as it is). Still it was giving memory fault !!! It should not have happened, because main() is empty. In that sense CC compiler was helpful since it was not allowing the wrong definition of functions also. After commenting function definition one by one, I found that there is a problem only with new(). After googling it I found it. Here they are, (1) not a major one : for using size_t one should include<stdlib.h> and for malloc-free include<malloc.h>. (2) The major problem is, you have defined new as, void* operator new(size_t sz) instead of void* operator new(size_t sz, int arg) // preferably int arg=0 This is expected since you are using new for int allocation (default int argument shoud be there whether you are giving it or not). Same for the float/double/struct allocations is preferred. Avoiding this default(second) argument will cause ambiguity for 'new', that which datatype is calling it, i.e. int *p = new int; and char *p = new char; and so on will be seen as same and that's why confusing. It might be taking 'void' (which is not valid) by default (who knows). Just add this 2 words(..., int arg=0) in your same code, and I hope it should start working fine as it is the case for my compiler. Let me know what result you are getting. I guess this explanation is sufficient. Thanks ! |
hey iammilind! thanks for the reply! very helpful! only problem is i cant compile the changed code:
:
#include <iostream>i get this error :
main.cpp: In function ‘void f()’::( im compiling using g++ (GCC) 4.0.2 20051125 (Red Hat 4.0.2-8). there should be a flag to fix this problem then? only problem is when i look at the GCC docs i get a headache, theres so much stuff in there and to make matters worse im clueless as to what i should be looking for! hope you can help! :) |
and to kill a bird with one stone (ahem, 2 posts for clarity) :D
ive got a problem getting overloaded new and delete to work in my application. as it turns out ive found what is causing the bug, its a call to delete... :
*** glibc detected *** ./test: free(): invalid pointer: 0x0958c664 ***so im trying to overload new/delete to find where the problem is coming from... heres what i get when i try to compile with overloaded new/delete :
#ifdef MTK_DEBUG:
clear; make clean; make testhope you can help! :) |
strange solution
I am refering to your earlier code which is appearing with following error after my solution,
main.cpp: In function ‘void f()’: main.cpp:26: error: call of overloaded ‘operator new(unsigned int)’ is ambiguous /usr/lib/gcc/i386-redhat-linux/4.0.2/../../../../include/c++/4.0.2/new:84: note: candidates are: void* operator new(size_t) main.cpp:9: note: void* operator new(size_t, int) This is strange solution but true, instead of writing, void* operator new(size_t sz, int arg=0) write void* operator new(size_t sz, int arg) It will start working. Earlier version confilicts with the library defined 'new' operator, because in that case we don't need to give the arg (default is taking care). However in later version we must have to give an argument. However I am not sure this is the reason, but the same error has got solved in my CC compiler after removing '=0' from 'int arg'. May be I din't check properly for int arg=0 and suggested you for the same. But isn't it a strange phenomena? |
heya! thanks for the reply!
ok i changed like you suggested from arg=0 to arg and it compiles fine, only problem is new is not overloaded anymore? heres my output: :
num of new 10as you can see no calls to overloaded new are made :confused: |
Sorry, iammilind, but you are mistaken in your advice.
If you supply an operator new() with a default argument value (that's what you get when you add the "=0" to the second argument) the result will be a compiler error due to ambiguity: the compiler has two operator new functions it can call, and no reason for preferring one over the other. If you supply an operator new with two arguments (and no default value for the second) you are simply overloading a function, and the operator new you supply will not be called. rwm, the linker errors you reported in post 6 of this thread are self-explanatory. Your linker is finding two operator new() functions -- the compiler/library supplied default and yours. The ways of addressing this are compiler/linker dependent. In effect, you need to ensure the linker only sees one of those functions. As I explained in another post, overriding operator new() and delete() are not the way to solve your problem. If you are getting a reported error with free() at run time, the real problem is not actually in the free() call. A basic rule of pointer molestation: if an error (eg a program crash) occurs, the real cause is code at or before the point where the crash occurs. If free() is reporting an invalid pointer, then you need to check the pointer supplied to free() -- and the code which supplied that pointer. |
heya! thanks for the reply and explanation!
ok, how can I force the linker to only see my version of new/delete? what I was gonna do is in my delete call is put in the line number and file so i can find out where the crash happens, then i could go from there and find the bug at or before the point of crash :
...im having trouble finding the point of crash - all g++ returns is :
*** glibc detected *** ./test: free(): invalid pointer: 0x08ac9664 ***i cant find the point of crash. sure the addresses are returned, but to me it means nothing. i dont know how to utilize these... sorry to be a ignorant ass but could you explain please! :eek: thanks! :) |
| All times are GMT -5. The time now is 2:36 AM. |
Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC