John
John

Reputation: 193

Overloading new and delete operator

In the following code:

#include <cstdio>
#include <cstdlib>
using namespace std;

void* operator new(size_t sz)    
{
   printf("operator new: %d Bytes\n", sz);  //LINE0
   void* m = malloc(sz);
   if(!m) puts("out of memory");
   return m;
}

void operator delete(void* m) {
   puts("operator delete");
   free(m);
}

class S {
    int i[100];
public:
    S() { puts("S::S()"); }
   ~S() { puts("S::~S()"); }
};

int main() {
  puts("creating & destroying an int");
  int* p = new int(47);   //LINE1
  delete p;
  puts("creating & destroying an s");
  S* s = new S;           //LINE2
  delete s;
  puts("creating & destroying S[3]");
  S* sa = new S[3];
  delete []sa;
} 

Below is the output of the code:

creating & destroying an int
operator new: 4 Bytes
operator delete
creating & destroying an s
operator new: 400 Bytes
S::S()
S::~S()
operator delete
creating & destroying S[3]
operator new: 1208 Bytes
    S::S()
    S::S()
    S::S()
    S::~S()
    S::~S()
    S::~S()
    operator delete

LINE1 passes argument "47" to the operator new. Why at LINE0, it becomes 4 Bytes? LINE2 does not pass a size argument to the operator new. Why the sz becomes 400 as printed at LINE0?

Upvotes: 2

Views: 134

Answers (4)

Let's break down some of your code first.

  • int(47) creates an integer with a value of 47.
  • operator new(size) simply allocates size bytes to be used and returns a pointer to that new memory space

When you're calling new int(47), you're implicitly calling operator new(sizeof(int))->int(47) - meaning that, since the output is 4, int is 4 bytes on your system.

Similarly, when you call new S, you're implicitly calling operator new(sizeof(S))->S(). Since S contains 100 int's, and each int is 4 bytes on your platform, you can now deduce that the sizeof(S) will be 400, which explains your output.

Upvotes: 1

Danke Xie
Danke Xie

Reputation: 1797

LINE1 "int* p = new int(47)" allocates one int element, that is, 4 bytes. 47 is the initial value of the allocated int element. If you mean to allocate an array, you should do "int *p = new int[47]", and the delete command would be "delete[] p".

LINE2 allocates one S object. Because S object contains an int array of 100 elements, its size is 100 * 4 = 400.

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 477570

You are not understanding this right. Your LINE1 does not "pass 47 to operator new". Rather, it passes sizeof(int) to operator new, and then creates an integer with value 47 in that memory.

Similarly, the code at LINE2 calls operator new with sizeof(S).


If you like the analogy, the statement T * p = new T(a, b, c); is roughly equivalent to this:

void * addr = operator new(sizeof(T));   // or T::operator new if available
T * p = new (addr) T(a, b, c);           // placement-new

In this analogy, delete p; has the following effect:

p->~T();
operator delete(addr);

Upvotes: 1

4pie0
4pie0

Reputation: 29754

Why at LINE0, it becomes 4 Bytes

because size of int is 4 bytes on this machine. The actual value of this integer, the 47 doesn't matter, the same size of 4 bytes will be allocated for any value of integer. The value 47 is used to initialize allocated memory.

LINE2 does not pass a size argument to the operator new(...)

the size of class S is visible to the compiler and it is passed implicitly as the first argument to the operator new. It is 400 because an array

int i[100];

contains 100 integers.

Upvotes: 0

Related Questions