0) { m_values = new int[m_size]; } IntArray::~IntArray() { delete [] m_values; } int & IntArray::operator[](size_t s){ if (!m_values || s >= m_size) { throw 1; } return m_values [s]; }"> 0) { m_values = new int[m_size]; } IntArray::~IntArray() { delete [] m_values; } int & IntArray::operator[](size_t s){ if (!m_values || s >= m_size) { throw 1; } return m_values [s]; }">
Download presentation
Presentation is loading. Please wait.
Published byBenjamin Fleming Modified over 8 years ago
1
CSE 332: Memory management with C++ classes Memory Management with Classes Review: for non-static built-in (native) types –default constructor and destructor do nothing –copy constructor and assignment operator (re-)value member-wise Review: variables vs. the pointers and references to them may have different scopes –May result in obvious kinds of lifetime errors –But may also introduce more subtle issues of aliasing –Can risk destroying an object too soon or too late Basic ideas in memory management with classes –Constructor allocates, destructor de-allocates: an object “owns” memory –Shallow copy vs. deep copy: aliasing vs. duplication
2
CSE 332: Memory management with C++ classes Constructor Allocates, Destructor De-allocates Resources allocated by an object need to be freed Constructor, destructor offer good start/end points Example: class to hold a fixed sized array –Can store integer values –Can access each element –Array size may differ for each object –Once set, object’s array size is fixed #ifndef INTARRAY_H #define INTARRAY_H class IntArray { public: IntArray(size_t); ~IntArray(); int & operator[](size_t); IntArray(const IntArray &); private: size_t m_size; int *m_values; }; #endif /* INTARRAY_H */
3
CSE 332: Memory management with C++ classes Constructor/Destructor, continued Initialization list sets m_size to the passed length, and also sets m_values to 0 Only allocate if length is greater than zero What does new do? –Allocates memory –Calls constructor(s) Destructor releases the allocated array via delete –Calls elements’ destructors –Returns memory to the heap #include “IntArray.h" IntArray::IntArray(size_t s) :m_size(s), m_values(0) { if (m_size > 0) { m_values = new int[m_size]; } IntArray::~IntArray() { delete [] m_values; } int & IntArray::operator[](size_t s){ if (!m_values || s >= m_size) { throw 1; } return m_values [s]; }
4
CSE 332: Memory management with C++ classes Constructor/Destructor, continued So, scopes are tied together –IntArray and its memory What does delete do? –Calls destructor(s) –Frees memory What are new [] and delete [] –vs. new and delete? What if m_values was 0 when delete was called on it? –Remember what happens? int main(int, char*[]) { IntArray a(6); // When a is created, it // usually allocates some // memory (here, 6 ints) return 0; // Now a is destroyed, and // since it’s destructor // is called, so is the // memory it allocated }
5
CSE 332: Memory management with C++ classes Copy Constructor: Shallow Copy There are two ways to “copy” –Shallow: aliases existing resources –Deep: makes a complete and separate copy Version above shows shallow copy –Efficient –But may be risky. Why? Hint: destructor (how to fix?) What’s the invariant established by this code? –Hint: what can we say about m_size and m_values? // just uses the array that’s already in the other object IntArray::IntArray(const IntArray &a) :m_size(a.m_size), m_values(a.m_values) { }
6
CSE 332: Memory management with C++ classes Copy Constructor: Deep Copy This code shows deep copy –Safe: no shared aliasing –But may not be very efficient Note trade-offs with arrays –Allocate memory once –More efficient than multiple calls to new (heap search) –Constructor and assignment called on each array element –Less efficient than block copy E.g., using memcpy() –But sometimes more correct i.e., constructors and destructors are called // makes its own copy of the array IntArray::IntArray(const IntArray &a) :m_size(a.m_size), m_values(0) { if (m_size > 0) { m_values = new int[m_size]; for (size_t i = 0; i < m_size; ++i) { m_values[i] = a.m_values[i]; }
7
CSE 332: Memory management with C++ classes Also Think About When to Use “new” Objects have to live beyond current scope –Is object copying a viable solution? Good for copy : Card objects –Object size is small –Non-polymorphic Bad for copy : Player, Game objects. –Involve heap memory allocation –Polymorphic –Is object swapping a good alternative? Good for objects with embedded heap objects such as –Player, –std::string –All STL containers, like »std::vector, std::set, std::map, …, etc. Not useful for polymorphic classes Game* makeGame(const char* name) { Game* result = 0; if (strcmp(name,”bridge”)==0) result= new BridgeGame; else if (strcmp(name,”hearts”)==0) result= new HeartsGame; return result; }
8
CSE 332: Memory management with C++ classes Summary: Memory Management With Classes Know what goes where in memory Understand the mechanics of stack vs. heap allocation Watch for simple lifetime errors Think about (and sketch) more subtle scope/lifetime issues Pay attention to aliasing issues Think about shallow copy vs. deep copy (problems/trade-offs)
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.