managing the heap resource acquisition is initialization (raii) overriding operator new and delete...

18

Upload: gary-moody

Post on 04-Jan-2016

224 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools
Page 2: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

Managing the heapResource acquisition is initialization

(RAII)Overriding operator new and

deleteClass-based memory pools

Page 3: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

The new and delete operators C++ does not have garbage collection

but it does have deterministic destructors! Can deallocate any resource

automatically not just memory! e.g., can unlock a mutex or close a

connection when a local object goes out of scope when you use delete no need for finally

Page 4: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

Two versions: Scalar (single object):

T* p = new T; // Calls constructor delete p; // Calls destructor

Array: T* p = new T[n]; // p points to first element delete [ ] p;

delete style must match the allocation ([ ])

Failing to delete is a memory leak

Page 5: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

“Resource Acquisition is Initialization” Memory is just one of many resources Treat all resources equally in C++:

Have a constructor acquire them

Have the destructor release them Example: file streams Example: raii.cpp

Page 6: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

Objects that emulate pointersThey hold the real pointer

but the wrapper object lives on the stack

its destructor calls delete on the real pointer

Overloaded operators: *

->

Page 7: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

It runs twice! First: it must return a “pointer-like thing” Next: operator-> is called again on that return value

Eventually a raw pointer must be returned

struct Foo {int x; int y;};

class FooWrapper { Foo* pf;public: FooWrapper(Foo* p) : pf(p) {} Foo* operator->() { cout << "returning a Foo*\n"; return pf; }};

int main() { Foo f = {1,2}; FooWrapper fw(&f); cout << fw->x << '\n'; cout << fw->y << '\n';}

/* Output:returning a Foo*1returning a Foo*2*/

Page 8: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

Creating a simple smart pointer SafePtr.cpp (generic version) smart.cpp (multi-level)

unique_ptr (uniqptr1-3.cpp, deleter1.cpp) unique_ptrs are not copyable

shared_ptr (sharedptr.cpp, deleter2.cpp) shared_ptrs increment their reference count

when copied And delete the raw pointer when count == 0

Page 9: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

<array> <functional> <memory> <regex> not implemented in gcc

:-( <tuple> <type_traits> <unordered_map> <unordered_set> <utility>

Page 10: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

Does the following before returning a pointer: Allocates needed memory on the heap▪ calls the library function operator new( )

Initializes the object by calling the proper constructor

Page 11: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

Does the following before returning a pointer to the first element: Allocates needed memory on the heap▪ calls the library function operator new[ ]( )

Initializes each object by calling the proper constructor

Page 12: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

Does 2 important things: Calls the destructor for the object Returns the memory to the free store▪ via the library function void operator

delete(void*)

Page 13: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

Calls the destructor for each object in the array

Returns the memory to the free store via void operator delete(void*);

You must use delete [ ] for arrays

Page 14: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

You can overload all 4 memory functions: operator new(size_t) operator new[ ](size_t) operator delete(void* ) operator delete[ ]( void*)

Can be useful for tracing memory operations

The array versions are seldom used See memory.cpp

Page 15: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

You can manage heap on a class basis Just provide operator new( ) and

operator delete( ) As member functions Must be static▪ Because they’re stand-alone functions, of course▪ Even if you don’t declare them so, they will still

be staticExample: memory2.cpp

Page 16: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

If you want to disallow allocating object on the heap, declare non-public class allocation functions:protected: void* operator new(size_t){return 0;} void operator delete(void*) {}

(It is an interesting mystery that on some platforms, bodies are required for these functions when you declare them)

Page 17: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools

A special-purpose version of the new operator used by library developers

see Lab 3 (you will be tested on it)

Page 18: Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools