home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / lang / cplus / 18080 < prev    next >
Encoding:
Text File  |  1992-12-16  |  3.3 KB  |  126 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!ngcgate!ngc!alexism
  3. From: alexism@ngc.com (Alexis Mermet)
  4. Subject: Re: Operator "new" - how to catch array-allocation?
  5. Message-ID: <BzDA4t.A6r@ngc.com>
  6. Organization: Network General Corporation
  7. References: <1992Dec14.143339.26314@daimi.aau.dk>
  8. Date: Wed, 16 Dec 1992 19:29:17 GMT
  9. Lines: 115
  10.  
  11. Here is a simple C++ program which overides the global new and delete 
  12. operators:
  13.  
  14. I would have expected that A * a = new A(5) calls the overloaded new
  15. operator, just as delete [] a should call the overloaded delete operator.
  16.  
  17. I tried on Borland C++ 3.1 and Microsoft c 7.0 and 
  18. *** THE RESULTS ARE DIFFERENT ***
  19. This is not argue who has the best C++, I just want to understand what is 
  20. done right, and what is done wrong.
  21.  
  22.  
  23. Borland:
  24. ~~~~~~~
  25. A* a = new A[5]
  26. The overloaded global new operator is ***not*** called
  27.  
  28. delete [] a;
  29. The overloaded global delete operator ***is*** called.
  30.  
  31. => makes quite a mess since the pointer received by the operator delete
  32. is not exactly what was given on the delete [] line. Somehow an extra field is
  33. hidden ( to know the size of the array I suppose ).
  34.  
  35. Even worse: if you use the new syntax with extra parameters like:
  36. A *a = new (__FILE__,__LINE__) A[5];
  37. and you have an operator new ( char* file, int line, size_t size ) then
  38. this operator new gets called. But the pointer it returns is returned as is to
  39. the application  ( with no offset added to hide the size field ) then when
  40. the application calls delete [] a, the operator deletes gets called with a 
  41. pointer that has been 'corrected' by the compiler to include this hidden 
  42. field. Therefore, delete screw the whole thing up!
  43.  
  44. In those conditions it is not possible to implement any reliable memory
  45. allocation tracking mechanism. There is even no way inside the delete
  46. operator to know whether this if for an array or a standard delete. Therefore
  47. there is no workaround.
  48.  
  49.  
  50. Microsoft:
  51. ~~~~~~~~~
  52. The overloaded global new and delete operator are both called.
  53.  
  54. => new returns an address. The program gets this address plus an offset 
  55. ( for a hidden field possibly like the size of the array ). Then when delete[]
  56. is called with this same address, delete gets called with the address minus 
  57. the offset, so deletes gets the same address as the one returned by new.
  58.  
  59. Seems the right way to do it for me.
  60.  
  61.  
  62. QUESTION:
  63. --------
  64. Who or What is right ?
  65.  
  66.  
  67. ------------------------------>> Test sample <<------------------------
  68.  
  69. #include <stdio.h>
  70. #include <malloc.h>
  71.  
  72. int cstr = 0;
  73. int dstr = 0;
  74. int allocated = 0;
  75. int freed = 0;
  76.  
  77. void * operator new ( size_t size );
  78. void operator delete ( void * ptr );
  79.  
  80. class A {
  81.     public:
  82.         A();
  83.         ~A();
  84. };
  85.  
  86. A::A()
  87. {
  88.     cstr++;
  89. }
  90.  
  91. A::~A()
  92. {
  93.     dstr++;
  94. }
  95.  
  96. void * operator new ( size_t size )
  97. {
  98.     allocated ++;
  99.     void * ptr = malloc( size );
  100.     printf("In new, about to return ptr 0x%lx\n",(unsigned long)ptr);
  101.     return ptr;
  102. }
  103.  
  104. void operator delete ( void * ptr )
  105. {
  106.     freed ++;
  107.     printf("In delete to free 0x%lx\n",(unsigned long)ptr);
  108.     free(ptr);
  109. }
  110.  
  111. int main()
  112. {
  113.     A *pa = new A[5];
  114.     printf("About to free address:0x%lx\n",(unsigned long)pa);
  115.     delete [] pa;
  116.     printf("cstr:%d   dstr:%d\n",cstr,dstr);
  117.     printf("alloc:%d  free:%d\n",allocated,freed);
  118.     return 0;
  119. }
  120.  
  121.  
  122. -- 
  123. Alexis MERMET-GRANDFILLES        Voice: 415-617-2943
  124. Software Engineer. R&D            Fax:   415-321-0855
  125. Network General Corp.
  126.