C ++ new grant delete

C ++ new grant delete

 

new operator 和 delete operator

new operator and the operator is delete operator ,

We know that the new operator will do two things: application memory and call the object constructor, for example, when we are a new string object:

string *ps = new string("Hands up!")

The actual compiler work something like this:

void * MEM = operator  new new ( sizeof ( String ));       // allocate memory 
Call String :: String ( " Hands up! " ) ON * MEM;      // call the constructor 
String * PS = static_cast < String *> (MEM) ;        // returns the string * pointers

 

Similarly, delete operator will dry matter 2: call object destructors and release memory

delete ps

The actual compiler work something like this:

ps->~string()
operator delete(ps)

 

The compiler sees the class type of new or delete operator when the first check whether there is a class operator new or operator delete members, if the class defines its own operator new and operator delete function, use these functions for the object allocation and free memory, or calls the standard library version (:: operator new and :: operator delete).

 one example:

struct foo {
    foo(int x) {m = x; printf("foo(%d)\n", m);}
    ~foo() {printf("~foo()\n");}
    int get() {printf("m=%d\n", m);}

    static void* operator new(size_t size) {
        printf("operator new()\n");
        return ::operator new(size);
    }   
    static  void  operator  delete ( void * ptr) {
        printf("operator delete()\n");
        :: operator  delete (ptr);
    }   

    private:
        int m;
};

int main () {
    foo* f = new foo(10);
    f->get();
    delete f;

    return 0;
}

Output

operator new()
foo(10)
m=10
~foo()
operator delete()

It is seen, when calling the new operator will first call the operator new () allocates memory and then calls the constructor; delete operator when calling, the first call the destructor, then call operator delete () frees the memory.

 


operator new() 和 operator delete()

operator new () and operator delete () is a function , with operator = () is similar.

expression:

void *operator new(size_t);
void *operator new[](size_t);
void  operator delete(void*);
void  operator delete[](void*);

As mentioned earlier, the global :: operator new () call is actually internal malloc memory allocation, and :: operator delete () call is free release internal memory.

operator new () and operator delete () can be overloaded.

 When overloaded operator new:

  • The first argument type must allocate space for the expression of the desired size (bytes), type size_t, in addition, can also take other parameters;
  • Only need to allocate space, but does not call the constructor; when unable to meet the required memory space, if there is new_handler, is called new_handler;

 

See a tape operator new additional parameters () Examples

struct foo {
    foo(int x) {m = x; printf("foo(%d)\n", m);}
    ~foo() {printf("~foo()\n");}
    int get() {
        printf("m=%d\n", m); 
    }   

    static void* operator new(size_t size, char* desc) {
        printf("operator new(%s)\n", desc);
        void* p = ::operator new(size);
        return p;
    }   
    static  void  operator  delete ( void * ptr) {
        printf("operator delete()\n");
        :: operator  delete (ptr);
    }   
    static  void  operator  delete ( void * ptr, char * dec) {
        printf("operator delete(%s)\n", desc);
        :: operator  delete (ptr);
    }   
    private:
        int m;
};

int main() {
    //foo* e = new foo(10); // Error,
    foo* f = new("hello") foo(10);
    f->get();
    delete f;

    return 0;
}

Output:

operator new(hello)
foo(10)
m=10
~foo()
operator delete()

Code,

foo * e = new foo (10 ) error occurs because the member function (member functions) name will function with the same name to cover the periphery. 
delete f call is operator delete () routine version.

Consider this, operator new () memory allocation successful, but inside the constructor throws an exception, runtime system (runtime system) has the responsibility to withdraw operator new () allocated performed. However, runtime system does not understand is called operator new () version is how it works, so that distribution of its own can not be undone. runtime system goes to look for a version of operator delete and operator new to hold the same number and type of additional parameters, such as:

struct foo {
    foo(int x) {
        m = x; printf("foo(%d)\n", m);
        throw this;
    }
    ~foo() {printf("~foo()\n");}
    int get() { printf("m=%d\n", m); }

    static void* operator new(size_t size, char* desc) {
        printf("operator new(%s)\n", desc);
        void* p = ::operator new(size);
        return p;
    }   
    static  void  operator  delete ( void * ptr) {
        printf("operator delete()\n");
        :: operator  delete (ptr);
    }   
    static  void  operator  delete ( void * ptr, char * dec) {
        printf("operator delete(%s)\n", desc);
        :: operator  delete (ptr);
    }   
    private:
        int m;
};

int main() {
    try {
        foo* f = new("hello") foo(10);
        f->get();
        delete f;
    } catch(void* e) {
        printf("catch exception");
    }

    return 0;
}

Output:

operator new(hello)
foo(10)
operator delete(hello)

At this time, operator delete is called with additional arguments, if not this additional parameter version, it creates a memory leak.

As above, the rules are simple: for a operator new with additional parameters (), you must provide both conventional operator delete (used in the construction process does not throw exception when (abnormal)), but also provides a hold the same operator new versions of additional parameters (for constructing abnormal situation).

 

Examples of the Look operator new [] and operator delete [] is:

struct foo {
    foo() {printf("foo()\n");}
    foo(int x) { m = x; printf("foo(%d)\n", m); }
    ~foo() {printf("~foo()\n");}
    int get() { printf("m=%d\n", m); }

    static void* operator new(size_t size) {
        printf("operator new(%d)\n", size);
        void* p = ::operator new(size);
        return p;
    }
    static void* operator new[](size_t size) {
        printf("operator new[](%d)\n", size);
        void* p = ::operator new[](size);
        return p;
    }   
    static void operator delete(void* ptr, size_t size) {
        printf("operator delete(%d)\n", size);
        :: operator  delete (ptr);
    }
    static void operator delete[](void* ptr, size_t size) {
        printf("operator delete[](%d)\n", size);
        :: operator  delete [] (ptr);
    }   
    private:
        int m;
};

int main() {
    const int len = 3;
    foo* f = new foo[len]();
    for (int n=0; n<len; n++) {
        f[n].get();
    }
    delete []f;

    return 0;
}

 

 

 

 

placement new

placement new () is an operator new () is a heavy-duty version, if you want to create an object in memory has been allocated using new is not enough.

placement new allows an already-allocated memory (heap or stack) Constructs a new object.

expression:

new(place_address) T
new(place_address) T(initializer_list)

among them,

  • place_address argument must be a pointer to a preallocated memory;
  • initializer_list provides initialization list (possibly empty), for use in construction of new objects allocated.

 

Look at an example:

struct foo {
    foo(int x) {m = x; printf("foo(%d)\n", m);}
    ~foo() {printf("~foo()\n");}

    private:
        int m;
};

int main() {
    void* addr = malloc(sizeof(foo));

    foo* p = new(addr) foo(10);
    p->~foo();

    free(p);

    return 0;
}

Visible, placement new can not use delete (because there is no application memory, placement new () no corresponding placement delete ()). Thus, to manually call the destructor.

 

You can also use the stack memory

struct foo {
    foo(int x) {m = x; printf("foo(%d)\n", m);}
    ~foo() {printf("~foo()\n");}
    int get() {printf("m=%d\n", m);}

    private:
        int m;
};

int main() {
    char mem[1024];

    foo* p = new(mem) foo(10);
    p->get();
    p->~foo();

    return 0;
}

 

 

 

Summary The following differences:

  • both new operator allocates memory, and building an object (the constructor), the opposite is the delete operator;
  • operator new (), just allocate memory, not build objects (do not call the constructor), the opposite is the operator delete ();
  • placement new (), regardless of the memory allocation, just call the constructor building object, this time manually manage memory, and separately destructor;

 

Guess you like

Origin www.cnblogs.com/chenny7/p/12103666.html