advanced programming & c++ language · advanced programming & c++ language heap management...

97
Dr. Miri (Kopel) Ben-Nissan Ariel University 2018 Advanced Programming & C++ Language Heap Management in C & C++ ~7~

Upload: others

Post on 25-Apr-2020

50 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

Dr. Miri (Kopel) Ben-NissanAriel University2018

Advanced Programming & C++ Language

Heap Management in C & C++

~7~

Page 2: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The Traditional Heap Manager 2

The standard C library routines for allocating and freeing memory are malloc() and free().

C++ uses the “new” and “delete” operators.

void* malloc ( size_t size );

void free ( void *memblock );

void* operator new (size_t);

void operator delete (void*);

void* operator new[](size_t);

void operator delete[](void*);

Page 3: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The Traditional Heap Manager (Cont…)

3

Main problem with those interfaces: they assumes the programmer never makes a mistake in calling the memory management functions. #include <stdlib.h>

int main(void)

{

void *pMem=malloc(100);

free(pMem);

free(pMem);

return 0;

}

<- behavior undefined!

Page 4: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The Traditional Heap Manager (Cont…)

4

Besides the interface, there is also general problems with dynamic memory allocations:

Allocation and de-allocation are non-deterministic with respect to time.

De-allocation:Explicit by the programmer can cause memory leaks if not

handled correctly. Implicit by garbage collector, nondeterministic.

Fragmentation problem.

Page 5: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

malloc5

void *malloc(long numbytes): This allocates numbytes of memory and returns a pointer to the first byte.Returns NULL if failed.Guaranties well fragmentation.

void free(void *firstbyte): Given a pointer that has been returned by a previous malloc, this gives the space that was allocated back to the process's "free space."

Page 6: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

malloc (cont…)

6

You can imagine the heap as a vector of bytes (characters), starting at address managed_memory_start, and last_valid_address as a pointer to the first available byte in the heap.

int has_initialized = 0;

void *managed_memory_start; //start of heap

void *last_valid_address; //end of heap

void *last_allocated= managed_memory_start;

//no allocations yet.

Malloc (Cont…)

Page 7: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

malloc (cont…)

7

A trivial implementation of malloc in C is:

void* malloc ( int size )

{

void* loc = last_allocated;

last_allocated += size;

return loc;

};

Malloc (Cont…)

Page 8: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

malloc (cont…)

8

If you always create dynamic structures but never delete them, you will eventually run out of heap space.

In that case, malloc will request the operating system for more heap. This is very expensive, because it may require to

move the stack data to higher memory locations.

Malloc (Cont…)

Page 9: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

malloc (cont…)

9

Alternatively, you can recycle the dynamically allocated data that you don't use.

This is done using free in C or delete in C++.

How we will know how many bytes to move the pointer back?

What if it is in the middle of the heap?

Page 10: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

malloc (cont…)

10

We will add an header to each allocated block in the heap:

struct mem_control_block

{

int is_available;

int size;

};

Page 11: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

malloc (cont…)

11

As said previously, the heap is a continues (in terms of virtual address) space of memory with three bounds: Starting point. Maximum limit. End point (break).

The break marks the end of the mapped memory spaces, that is, the part of the virtual address space that has correspondence into real memory.

Page 12: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

12

In the Unix operating system, we find the following two system calls that enables us to control the break border:

brk places the break at the given address addr and returns 0 if successful, -1 otherwise.

sbrk moves the break by the given increment (in bytes). Depending on system implementation, it returns the previous or the new break address. On failure, it returns (void*)-1. On some systems, sbrk accepts negative values (in order to free some mapped memory).

malloc (cont…)

Page 13: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

malloc (cont…)

13 when increment is null (i.e. sbrk(0)), the returned value is the

actual break address. sbrk is thus used to retrieve the beginning of the heap which is

the initial position of the break.

Accessing addresses above the break should trigger a bus error. The remaining space between the break and the maximum limit of the heap is not associated to physical memory by the virtual memory manager of the system.

Page 14: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

14

#include <unistd.h> /* Include the sbrk function */

int has_initialized = 0;

void *managed_memory_start;

void *last_valid_address;

void malloc_init()

{

/* grab the last valid address from the OS */

last_valid_address = sbrk(0);

/* we assume that managed memory size at the beginning

* is empty, so just set the beginning to be

* last_valid_address */

managed_memory_start = last_valid_address;

has_initialized = 1;

}

malloc (cont…)

Page 15: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

15

struct mem_control_block {

int is_available;

int size;

};

void free(void *firstbyte)

{

struct mem_control_block *mcb;

mcb = firstbyte - sizeof(struct mem_control_block);

mcb->is_available = 1;

return;

}

malloc (cont…)

Page 16: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

16

void *malloc(long numbytes)

{

/* Holds where we are looking in memory */

void *current_location;

/* This is the same as current_location, but cast to a

memory_control_block */

struct mem_control_block *current_location_mcb;

void *memory_location;

if(! has_initialized) {

malloc_init();

}

malloc (cont…)

Page 17: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

17

numbytes = numbytes + sizeof(struct mem_control_block);

/* Set memory_location to 0 until we find a suitable location */

memory_location = 0;

/* Begin searching at the start of managed memory */

current_location = managed_memory_start;

TH

E H

EA

P

numbytesheadermanaged_memory_start

current_location

last_valid_address

malloc (cont…)malloc (cont…)

Page 18: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

18

/* Keep going until we have searched all allocated space */

while(current_location != last_valid_address)

{

current_location_mcb =

(struct mem_control_block *)current_location;

if(current_location_mcb->is_available){

if(current_location_mcb->size >= numbytes){

current_location_mcb->is_available = 0;

memory_location = current_location;

break;

}

}

/* If we made it here, it's because the current memory

* block not suitable, move to the next one */

current_location = current_location +

current_location_mcb->size;

}

malloc (cont…)

Page 19: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

19

/* If we still don't have a valid location, we'll have to ask the

operating system for more memory */

if(! memory_location)

{

/* Move the program break numbytes further */

if (sbrk(numbytes) == (void*)(-1))

return 0; /*unable to resize heap size.*/

/* The new memory will be where the last valid address left off*/

memory_location = last_valid_address;

/* We'll move the last valid address forward numbytes */

last_valid_address = last_valid_address + numbytes;

/* We need to initialize the mem_control_block */

current_location_mcb =

(struct mem_control_block *)memory_location;

current_location_mcb->is_available = 0;

current_location_mcb->size = numbytes;

}

malloc (cont…)malloc (cont…)

Page 20: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

20

/* Move the pointer past the mem_control_block */

memory_location =

memory_location + sizeof(struct mem_control_block);

/* Return the pointer */

return memory_location;

}

Taken from:

http://www.ibm.com/developerworks/linux/library/l-memory/

malloc (cont…)

Page 21: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Exercise21

Write an aligned malloc & free function, which takes two parameters: The number of bytes to allocate. The aligned byte (which is always power of 2).

Example: align_malloc (1000,128);

will allocate the memory and return a memory address which is a multiplication of 128.

aligned_free();

will free memory allocated by align_malloc.

malloc (cont…)

Page 22: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

In their turn, malloc and newmake calls to theoperating system kernel requesting memory, whilefree and deletemake requests to release memory. This means that the operating system has to switch

between user-space code and kernel code every

time a request for memory is made .smargorP

gnikamdetaepersllacot malloc or new eventuallyrun slowly because of the repeated contextswitching .

Page 23: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Allocation Policies

23

Allocation Policy = The concrete policy used by an allocator (memory manager) for choosing a free block to satisfy an allocation request.

Two methods: Fixed size blocks. Variable size blocks.

Most popular policies (for both methods): First Fit Best Fit Next Fit

Page 24: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

24

Notice: malloc allocates “pages” (or “chunks”) of fixed size. Than this chunk is split: part of it goes to the user, and the rest goes to the free-blocks list.

Allocation Policies (Cont…)

Page 25: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Allocation Policies (Cont…)

Best-fit: choose smallest hole that fits creates small holes!

First-fit: choose first hole from beginning that fits

generally superior

Next-fit: variation: first hole from last placement that fits.

(also worst fit)

Page 26: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Allocation Policies (Cont…)

26

First fit simply searches the free list from the beginning, and uses the first free block large enoughto satisfy the request. If the block is larger than necessary, it is either used as is (internal

fragmentation) or split and the remainder is put on the free list.

Easy to implement Memory overhead is small.

Internal fragmentation. Lots of small blocks at the beginning

Page 27: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Allocation Policies (Cont…)

27

Best Fit always allocates from the smallest suitable free block. In theory, best fit may exhibit bad fragmentation, but

in practice this is not commonly observed.

Minimizes the amount of wasted space

Sequential best-fit is inefficient

Page 28: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Allocation Policies (Cont…)

28

Next Fit is a variant of the first fit allocation mechanism that uses a roving pointer on a circular free block chain. Each allocation begins looking where the previous one

finished.

No accumulation of small blocks, which would have to be examined on every allocation.

Generally increases fragmentation, like first-fit. Tendency to spread related objects out in memory. Gives quite poor locality for the allocator (as the roving

pointer rotates around memory, the free blocks touched are those least-recently used).

Page 29: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Allocation Policies (Cont…)

29

All algorithms can be improved by keeping the information about the free blocks in the heap.

There are many techniques for that, like: Free-page bitmap. Free list.And many more…

Some of the techniques allocates fixed-size blocks and other a variable-sized blocks.

Page 30: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Allocation Policies (Cont…)

30

Free-page bitmap. Every bit in the bitmap represents one 4096 byte (4KB) block in the heap. If the bit is 0, the block has been allocated. If the bit is 1, then it is free.

The free page bitmap is 1024 bits wide: 4MB = 4096KB => 4096KB/4096B = 1024.

Assume a 4MB

heap.

Each allocated

block is 4KB.

allocation: O(N)

free: O(1)

Page 31: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Allocation Policies (Cont…)

31

Free list is a linked list of freeblock structures.

struct freeblock

{

struct freeblock *next;

char garbage[4092];

};

In the data portion of the processes, we

store a pointer which points to the first

freeblock structure.Internal fragmentation !

Page 32: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Allocation Policies (Cont…)

32

Variable Size Allocations allows the allocation of memory of variable sizes.

Instead of having several smaller blocks to allocate, we start with one big block of memory and split it as necessary to make smaller blocks.

struct freeblock

{

struct freeblock *next;

size_t size;

};

Page 33: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Segregated free lists uses a set of lists of free blocks. Each list holds blocks of a given size

A freed block is pushed onto the relevant list When a block is needed, the relevant list is used

Allocation Policies (Cont…)

Page 34: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Block Headers Policies34

There are two techniques used to handle the headers of the allocated blocks:

Over-allocate the array and put n just to the left of the beginning of the block.

Use an associative array with p as the key and n as the value.

Page 35: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Block Headers Policies (Cont…)

35

Using "over-allocation" (header) to keep the size of the block size.

Each block, allocated or freed, contains a header.

Usually the heap simply consists of two lists of cells; one is the list of allocated cells and the other the list of free cells.

Page 36: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

36

Block Headers Policies (Cont…)

Page 37: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

37

Using an "associative array" to remember the size of the block.

An associative array, like a STL map data structure, is used to map a pointer of a block to its size.

The header is kept outside the area of allocated blocks, thus the block size is only the requested size sent by the user to malloc.

Block Headers Policies (Cont…)

Page 38: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Memory Allocation in C++38

Even though malloc and free are available in C++, their use is not recommended.

It is always preferred to use new and delete, especially when working with objects. new and delete point to the correct memory type (they are type

safe), so casts are not necessary. new invokes the constructor, allowing the initialization of

objects, and delete invokes the destructor. new figures out the size it needs to allocate, so the programmer

doesn't have to specify it. new throws an exception of type std::bad_alloc when it fails,

instead of only returning a NULL pointer like malloc.

Page 39: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

new and delete39

void* operator new(size_t);

void operator delete(void*);

void* operator new[](size_t);

void operator delete[](void*);

Page 40: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operators40

Do I need to check for NULL after “p = new Fred()”?

Page 41: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operator (Cont…)

41Attempt to

allocate

memory

Return the

address

Call the

handler

function

Throw

bad_alloc

Handler

installed?

yesno

success

failure

retry

Page 42: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operators (Cont…)

42

Do I need to check for NULL after “p = new Fred()”?

Do NOT check for NULL when allocating memory with new, since new will never return NULL!

The ptrwill retain its previous value.

Malloc can fail. When you call malloc, or when you get a pointer back from a function that calls malloc, you should check to ensure that the pointer you got back wasn't NULL.

Page 43: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operators (Cont…)

43

Until the early 1990s, operator new behaved very much like standard C's malloc(), as far as allocation failures were concerned. When it failed to allocated a memory block of the requested size, it would return a NULL pointer.

This behavior was changed in the early 1990s. Instead of returning a NULL pointer, new throws an exception of type std::bad_alloc to indicate a failure.

Testing the return value is utterly wrong.

Page 44: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operators (Cont…)

44

p = new CMyClass;

if (!p){ //not to be used under ISO

//compliant compilers

cout<<"allocation failure!“;

exit(1);

}

The “if” condition is never evaluated in the event of an allocation failure, because the exception thrown by new has already transferred control to a matching catch() clause, if one exists.

If no matching catch() is found, C++ automatically calls function terminate() that terminates the program unconditionally.

Page 45: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

45

try

{

p = new DerivedWind;

}

catch (std::bad_alloc &ba)

{

cout<<"allocation failure!“;

//...additional cleanup

}

Embedded systems don't always support exceptions. In such environments, nothrow new can be rather

useful.

The new & delete operators (Cont…)

Page 46: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operator (Cont…)

46

Before operator new throws an exception, it calls a client-specified error-handling function, called a new-handler.

To specify the out-of-memory-handling function, clients call set_new_handler, a standard library function declared in <new>:

namespace std

{

typedef void(*new_handler_ptr)();

//ptr to function

new_handler set_new_handler(new_handler_ptr p)

throw();

}

Page 47: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operator (Cont…)

47

Example:

void OutOfMem()

{

std::cerr<<“Failed to allocate memory\n”;

std::abort();

}

int main()

{

std::set_new_handler(OutOfMem);

int* pBigDataArray = new int[499999999L];

//…

}

Page 48: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operator (Cont…)

48

A well designed new-handler function must do one of the following:

Make more memory available. Install a different new-handler.De-install the new-handler, by passing NULL to set_new_handler. Like this the new operator will throw an exception.

Throw an exception.No return (abort or exit).

Page 49: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operator (Cont…)

49

Further reading at home:

Handling memory failures in different ways, depending on the class of the object being allocated.(Effective C++, pages 242-247).

Page 50: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operators (Cont…)

50

Do I need to check for NULL before “delete p”?

No!

The C++ language guarantees that delete pwill do nothing if p is equal to NULL.

Wrong: if (p != NULL)

delete p;

Right: delete p;

Page 51: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operators (Cont…)

51

What are the two steps that happen when I say delete p?

“delete p” is a two-step process: It calls the destructor, then releases the memory.

The code generated for “delete p” is functionally similar to this (assuming p is of type Fred*):

// Original code: delete p;if (p != NULL) {p->~Fred();operator delete(p);

}

Page 52: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operators (Cont…)

52

The statement p->~Fred() calls the destructor for the Fred object pointed to by p.

The statement “operator delete(p)” calls the memory de-allocation primitive,

void operator delete(void* p).

This primitive is similar in spirit to free(void* p). (Note, however, that these two are not

interchangeable; e.g., there is no guarantee that the two memory de-allocation primitives even use the same heap!)

Page 53: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The new & delete operators (Cont…)

53

Operator New:Call new(sz) operator.Call the constructor.

Operator DeleteCall the destructorCall the delete(p) operator.

Page 54: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete54

When you overload operator new and operator delete, you’re changing only the way raw storage is allocated. The compiler will simply call your new instead of the

default version to allocate storage, then call the constructor for that storage.

So, although the compiler allocates storage and calls the constructor when it sees new, all you can change when you overload new is the storage allocation portion. (delete has a similar limitation).

Page 55: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete (Cont…)

55

When you overload operator new, you also replace the behavior when it runs out of memory, so you must decide what to do in your operator new. (return zero, write a loop to call the new-handler

and retry allocation, or (typically) throw a bad_alloc exception).

Page 56: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading global new & delete56

When the global versions of new and delete are unsatisfactory for the whole system.

If you overload the global versions, you make the defaults completely inaccessible – you can’t even call them from inside your redefinitions.

The overloaded new must take an argument of size_t (the Standard C standard type for sizes).

The return value of operator new is a void*, nota pointer to any particular type.

Page 57: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading global new & delete (Cont…)

57

You must return a pointer either to an object of that size (or bigger, if you have some reason to do so), or to zero if you can’t find the memory (in which case the constructor is not called!).However, if you can’t find the memory, you should

probably do something more drastic than just returning zero, like calling the new-handler or throwing an exception, to signal that there’s a problem.

Page 58: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading global new & delete (Cont…)

58

The operator delete takes a void* to memory that was allocated by operator new .

It’s a void* because you get that pointer afterthe destructor is called, which removes the object-ness from the piece of storage. The return type is void.

Page 59: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

59

Overloading global new & delete (Cont…)

#include <cstdio>

#include <cstdlib>

using namespace std;

void* operator new(size_t sz)

{

printf("operator new: %d Bytes\n", sz);

void* m = malloc(sz);

if(!m) puts("out of memory");

return m;

}

void operator delete(void* m)

{

puts("operator delete");

free(m);

}

Page 60: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

60

Overloading global new & delete (Cont…)

class S

{

int i[100];

public:

S() { puts("S::S()"); }

~S() { puts("S::~S()"); }

};

Page 61: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

61

Overloading global new & delete (Cont…)

int main()

{

puts("creating & destroying an int");

int* p = new int(47);

delete p;

puts("creating & destroying an s");

S* s = new S;

delete s;

puts("creating & destroying S[3]");

S* sa = new S[3];

delete []sa;

}

Page 62: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for a class62

When you overload new and delete for a class, you’re creating static member functions.The operators are implicitly declared as static, even if

you didn’t specify it.

When the compiler sees you use new to create an object of your class, it chooses the member operator new over the global version. The global versions of new and delete are used for all

other types of objects (unless they have their own newand delete).

Page 63: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

63

Overloading new & delete for a class (Cont…)class MemBlock

{

public:

enum{BLOCK_SIZE=10, MAX_POOL_SIZE=100};

public:

MemBlock();

~ MemBlock();

void* operator new(size_t);

void operator delete(void*);

private:

char c[BLOCK_SIZE]; //not used, just to have

//a size of the block.

static unsigned char _pool[];

static unsigned char _alloc_map[];

};

H File

Page 64: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

64

Overloading new & delete for a class (Cont..)

unsigned char

MemBlock::_pool[MAX_POOL_SIZE*sizeof(MemBlock)];

//one byte for every block

unsigned char

MemBlock::_alloc_map[MAX_POOL_SIZE] = {0};

ofstream local_out("MemBlock.out"); //log file

MemBlock::MemBlock()

{ local_out << "MemBlock()\n"; }

MemBlock::~MemBlock()

{ local_out << "~MemBlock() ... "; }

CPP File

Page 65: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

65

Overloading new & delete for a class (Cont..)

// Size is ignored -- assume a Framis object

void* MemBlock::operator new(size_t)

{

for(int i = 0; i < MAX_POOL_SIZE; i++)

{

if(!_alloc_map[i])

{

local_out<<"using block "<<i<<"...";

_alloc_map[i] = 1; //Mark it used

return _pool + (i * sizeof(MemBlock));

}

}

local_out << "out of memory" << endl;

return NULL;

}

Page 66: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

66

Overloading new & delete for a class (Cont..)

void MemBlock::operator delete(void* ptr)

{

if(!ptr)

{

return; // Check for null pointer

}

// Calculate which block number it is:

unsigned long block =

(unsigned long)ptr - (unsigned long)_pool;

block /= sizeof(MemBlock);

local_out << "freeing block " << block << endl;

// Mark it free:

_alloc_map[block] = 0;

}

Page 67: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

67

Overloading new & delete for a class (Cont..)

int main ()

{

MemBlock* f[MemBlock::MAX_POOL_SIZE];

for(int i=0; i<MemBlock::MAX_POOL_SIZE; i++){

f[i] = new MemBlock;

}

new MemBlock; // Out of memory

delete f[10];

f[10] = 0;

MemBlock* x = new MemBlock;

delete x;

for(int j=0; j<MemBlock::MAX_POOL_SIZE; j++){

delete f[j]; // Delete f[10] OK

}

}

Main File

Page 68: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays 68

If you overload operator new and delete for a class, those operators are called whenever you create an object of that class.

However, if you create an array of those class objects, the global operator new is called to allocate enough storage for the array all at once, and the global operator deleteis called to release that storage.

You can control the allocation of arrays of objects by overloading the special array versions of operator new[ ] and operator delete[ ] for the class.

Page 69: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

69

Overloading new & delete for arrays (Cont…)

MyType* fp = new MyType[100];

MyType* fp2 = new MyType;

delete fp2; // OK

delete fp; // Not the desired effect

The destructor will be called for the MyType object pointed to by the given address, and then the storage will be released.

For fp2 this is fine, but for fp this means the other 99 destructor calls won’t be made.

The proper amount of storage will still be released, however, because it is allocated in one big chunk, and the size of the whole chunk is stashed somewhere by the allocation routine.

Page 70: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays (Cont…)

70

delete []fp;

The empty brackets tell the compiler to generate code that fetches the number of objects in the array, stored somewhere when the array is created, and calls the destructor for that many array objects.

Page 71: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

71

Overloading new & delete for arrays (Cont…)

class Widget

{

public:

enum {SZ = 10};

Widget();

~Widget();

void* operator new(size_t sz) throw();

void operator delete(void* p);

void* operator new[](size_t sz) throw();

void operator delete[](void* p);

private:

int i[SZ ];

};

Page 72: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

72

Overloading new & delete for arrays (Cont…)

ofstream trace("ArrayNew.out");

Widget::Widget() { trace << "*"; }

Widget::~Widget(){ trace << "~"; }

void* Widget::operator new(size_t sz)

throw (std::bad_alloc)

{

trace<<"\nWidget::new: “<<sz<<" bytes\n";

return ::new char[sz];

}

void Widget::operator delete(void* p)

{

trace << "\nWidget::delete" << endl;

::delete []p;

}

Page 73: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

73

Overloading new & delete for arrays (Cont…)

void* Widget::operator new[](size_t sz)

throw (std::bad_alloc)

{

trace << "\nWidget::new[]: "

<< sz << " bytes" << endl;

return ::new char[sz];

}

void Widget::operator delete[](void* p)

{

trace << "\nWidget::delete[]" << endl;

::delete []p;

}

Page 74: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

74

Overloading new & delete for arrays (Cont…)

int main()

{

trace << "new Widget" << endl;

Widget* w = new Widget;

trace << "\ndelete Widget" << endl;

delete w;

trace << "\nnew Widget[25]" << endl;

Widget* wa = new Widget[25];

trace << "\ndelete []Widget" << endl;

delete []wa;

return 0;

}

Page 75: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays (Cont…)

75

new Widget

Widget::new: 40 bytes

*

delete Widget

~

Widget::delete

new Widget[25]

Widget::new[]: 1004 bytes

*************************

delete []Widget

~~~~~~~~~~~~~~~~~~~~~~~~~

Widget::delete[]

Page 76: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays (Cont…)

76

After p = new Fred[n], how does the compiler know there are n objects to be destructed during delete[ ] p?

The run-time system stores the number of objects, n, somewhere where it can be retrieved if you only know the pointer, p.

There are two popular techniques that do this. Both these techniques are in use by commercial-grade compilers, both have tradeoffs, and neither is perfect.

Page 77: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays (Cont…)

77

These techniques are:

Over-allocate the array and put n just to the left of the first Fred object.

Use an associative array with p as the key and n as the value.

We saw those techniques before…

Page 78: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays (Cont…)

78

Using "over-allocation" (header) to remember the number of elements in an allocated array.

Each block, allocated or freed, contains a header.

Usually the heap simply consists of two lists of cells; one is the list of allocated cells and the other the list of free cells.

Page 79: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

79

Overloading new & delete for arrays (Cont…)

Page 80: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

80

Overloading new & delete for arrays (Cont…)

char* tmp =

(char*)operator new[](WORDSIZE + n*sizeof(Fred));

Fred* p = (Fred*) (tmp + WORDSIZE);

*(size_t*)tmp = n;

size_t i;

try

{

for (i = 0; i < n; ++i)

new(p + i) Fred(); // Placement new

}

catch (...)

{

while (i-- != 0)

(p + i)->~Fred(); // Explicit call to the destructor

operator delete[] ((char*)p - WORDSIZE);

throw;

}

p = new Fred[n] code:

Page 81: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays (Cont…)

81

Then the delete[] p statement becomes:

// Original code: delete[] p;

size_t n = *(size_t*)((char*)p-WORDSIZE);

while (n-- != 0)

(p + n)->~Fred();

operator delete[] ((char*)p - WORDSIZE);

Page 82: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays (Cont…)

82

Note that the address passed to operator delete[] is not the same as p.

If you make a programming error by saying delete pwhere you should have said delete[] p, the address that is passed to operator delete(void*) is not the address of any valid heap allocation. This will probably corrupt the heap.

Page 83: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays (Cont…)

83

Using an "associative array" to remember the number of elements in an allocated array

In this technique, the code for p = new Fred[n] looks something like this (where arrayLengthAssociation is the imaginary name of a hidden, global associative array that maps from void* to "size_t"):

Page 84: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

84

Overloading new & delete for arrays (Cont…)

Fred* p=(Fred*)operator new[] (n * sizeof(Fred));

size_t i;

try {

for (i = 0; i < n; ++i)

new(p + i) Fred(); // Placement new

}

catch (...) {

while (i-- != 0)

(p + i)->~Fred();

// Explicit call to the destructor

operator delete[] (p);

throw;

}

arrayLengthAssociation.insert(p, n);

Page 85: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays (Cont…)

85

Then the delete[] p statement becomes: size_t n=arrayLengthAssociation.lookup(p);

while (n-- != 0)

(p + n)->~Fred();

operator delete[] (p);

If you make a programming error by saying delete p where you should have said delete[] p, only the first Fred in the array gets destructed, but the heap maysurvive (unless you've replaced operator delete[] with something that doesn't simply call operator delete, or unless the destructors for the other Fred objects were necessary).

Page 86: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Overloading new & delete for arrays (Cont…)

86

The “Over-Allocation” technique is faster, but more sensitive to the problem of programmers saying delete p rather than delete[] p.

The “associative array” technique is slower, but less sensitive to the problem of programmers saying delete p rather than delete[] p.

Page 87: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Constructor calls 87

MyType* f = new MyType;

Assume we call new to allocate a MyType-sized piece of storage.

This call invokes the MyType constructor on that storage.

What happens if all the safeguards fail and the value returned by operator new is zero?

Page 88: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Constructor calls (Cont…)

88

The constructor is not called in that case, so although you still have an unsuccessfully created object, at least you haven’t invoked the constructor and handed it a zero pointer.

Page 89: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

89

Constructor calls (Cont…)

void my_new_handler()

{

cout << "new handler called" << endl;

}

class NoMemory

{

public:

NoMemory(){cout<<"NoMemory::NoMemory()"<<endl;}

void* operator new(size_t sz) throw(bad_alloc)

{

cout << "NoMemory::operator new" << endl;

//throw bad_alloc(); // "Out of memory"

return 0;

}

};

Page 90: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

Constructor calls (Cont…)

90

int main()

{

set_new_handler(my_new_handler);

NoMemory* pNM = new NoMemory;

cout << “pNM = " << pNM << endl;

return 0;

}

Page 91: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

placement new

91

Used to construct an object on a pre-allocated storage. The overloaded operator new can take more than one

argument. The first argument is always the size of the object, which is

secretly calculated and passed by the compiler. The other arguments can be anything you want: the address

you want the object placed at, a reference to a memory allocation function or object, or anything else that is convenient for you.

Page 92: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

The way you pass the extra arguments to operator new during a call may seem slightly curious at first: You put the argument list ( withoutthe size_t argument, which is handled by the compiler) after the keyword new and before the class name of the object you’re creating.

placement new (Cont…)

Page 93: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

93

placement new (Cont…)

class X{

int i;

public:

X(int ii = 0) : i(ii) {}

~X() { cout << "X::~X()" << endl; }

void* operator new(size_t, void* loc) { return loc; }

};

int main() {

int vec[10]={};

X* xp = new(vec) X(7); // X at location vec

xp->X::~X(); // Explicit destructor call

// ONLY use with placement!

return 0;

}

example 1:

Page 94: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

placement new (Cont…)

94

class Data {

public:

int x;

};

void* pMemPool = malloc(256);

void* pNextAlloc = pMemPool ;

Data* pData = new (pNextAlloc) Data();

pNextAlloc = (char*)(pNextAlloc) + sizeof(Data);

// Writing to it

pData->x = 10;

// Destroying c

pData->~Data();

pNextAlloc = (char*)(pNextAlloc) - sizeof(Data);

free(pMemPool); pMemPool=NULL; pNextAlloc=NULL;

example 2: mini memory pool

Page 95: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

placement new (Cont…)

95

There’s only one version of operator delete , so there’s no way to say, “Use my special de-allocator for this object.”

You want to call the destructor, but you don’t want the memory to be released by the dynamic memory mechanism because it wasn’t allocated on the heap.

You can explicitly call the destructor, as in xp->X::~X(); // Explicit destructor call

You will have serious problems if you call the destructor this way for an object created on the stack because the destructor will be called again at the end of the scope.

If you call the destructor this way for an object that was created on the heap, the destructor will execute, but the memory won’t be released, which probably isn’t what you want.

Page 96: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

96

nothrow new and deleteextern const nothrow_t nothrow;

This constant value is used as an argument for operator new and operator new[] to indicate that these functions shall not throw an exception on failure, but return a null pointer instead. This version cannot be replaced by the user.

int main () {

cout << "Attempting to allocate 1 MB..."; char* p = new (nothrow) char [1048576]; if (p==0)

cout << "Failed!\n"; else {

cout << "Success!\n"; delete[] p;

} return 0;

}

Page 97: Advanced Programming & C++ Language · Advanced Programming & C++ Language Heap Management in C & C++ ~7~ ... problems with dynamic memory allocations: Allocation and de-allocation

© Miri Ben-Nissan

summary

97

The standard-provided overloads of operator new (there are also corresponding ones for array new[ ]):

void* ::operator new(std::size_t size)

throw(std::bad_alloc);

// usual plain old boring new

// usage: new T

void* ::operator new(std::size_t size,

const std::nothrow_t&) throw();

// nothrow new

// usage: new (std::nothrow) T

void* ::operator new(std::size_t size, void* ptr) throw();

// in-place (or "put-it-there") new

// usage: new (ptr) T