Download presentation
Presentation is loading. Please wait.
1
Computing Fundamentals with C++
Object-Oriented Programming and Design, 2nd Edition Rick Mercer Franklin, Beedle & Associates, 1999 ISBN Presentation Copyright 1999, Franklin, Beedle & Associates Students who purchase and instructors who adopt Computing Fundamentals with C++, Object-Oriented Programming and Design by Rick Mercer are welcome to use this presentation as long as this copyright notice remains intact.
2
Chapter 15 Dynamic Memory Management
Chapter Objectives Grow and shrink primitive C arrays Manipulate pointers to a collection of chars Use the new and delete operators for memory management Recognize and use pointer objects within classes Implement destructor member functions Understand how the capacity of an object may grow and/or shrink at runtime Implement destructors and copy constructors member functions
3
15.1 The Primitive C Array C++ has primitive arrays Examples:
string myFriends[100]; // store up to 100 strings double x[10000]; // store up to numbers There is no range checking with these actually, only the vector with this book has subscript range checking You need to set include paths right the STL vector does not Still need default constructors for programmer-defined classes
4
Compare C arrays to vector
5
15.1.2 The Array/Pointer Connection
A primitive array is actually a pointer The array name is actually the memory location of the very first array element Individual array elements are referenced like this address of first array element + ( subscript * size of one element) Arrays are automatically passed by reference But a different syntax is required void init(int x[ ], int & n) // both x and n are reference parameters
6
Array parameters are reference parameters
When passing arrays as parameters, you don't need &. Just write it as an array x and anarray are the same objects
7
15.2 char* Objects With this declaration, strPtr points to the first of possibly many characters: char * strPtr; strPtr = "Barbie"; A null character '\0' is a automatically appended at the end of the string literal strPtr now stores the address of the char 'B' strPtr B a r b i e \0
8
Careful with char* Some strange things can happen with char*
Consider this code char* wife; // Two pointers that store addresses char* husband; // of null-terminated strings wife = "Joann"; husband = "Charlie"; husband = wife; cout << "wife: " << wife << endl; husband[0] = 'T'; husband[4] = 't' Output wife: Joann wife: Toant Changes to husband changed wife! Both point to the same place, addresses are equal
9
15.2.1 A Few <cstring> Functions
Several string functions use the address of the first char and the null char '\0' to implement a quasi string data type (see functions string.h functions, strcpy, strcmp, strlen––page 432) strcpy(strPtr, "Another string"); cout << strlen(strPtr); Demonstrate primitive string variables and one problem with "charstar.cpp" Optional Demo: charstar.cpp
10
Be Careful with char* Objects
Programs with char* objects require care to avoid program crashes To be safe, allocate memory like this char strPtr[100]; Or use the C++ new operator coming up a preview char* strptr = new char[100];
11
Static and Dynamic Memory Allocation
Some objects take a fixed amount of memory at compiletime: char int double Other objects require varying amounts of memory that is allocated and deallocated dynamically, that is, at runtime string for example string objects change size during assignment and input Pointer objects are used when memory is dynamically allocated
12
15.3 Initializing Pointers with new
The new operator allocates a specified amount of memory and returns the address of that memory General form: new class-name Example used to initialize intPtr: // dynamically allocate sizeof(int) bytes intPtr = new int; Now intPtr point to a dynamically allocated (done at runtime) memory location
13
Allocating More than One Object with new
General form to allocate memory for many objects in contiguous memory (arrays): new class-name [ number-of-elements ] Example used to initialize strPtr: char* name; int n = 10; // Dynamically allocate 10 bytes name = new char[n]; // name, array of chars name = "Ken"; name 'K' 'e' 'n' '\0' ? ? ? ? ? ? [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
14
Dynamic Memory Allocation
Here is on example of dynamic memory allocation you have been using for a long time The string constructor below is called with // Call constructor string name("Barbie and Ken"); This calls the constructor that dynamically allocates memory for name string::string(char* initText) { // construct a string object with // precisely enough memory len = strlen(initText); theChars = new char[len + 1]; // +1 for '\0' strcpy(theChars, initText); }
15
15.5 Copy Constructors Memberwise copy
by default, C++ will copy each data member during assignment and argument/parameter associations works well unless the data member is a pointer When a pointer is copied by memberwise copy, you have two objects pointing to the same object when one object gets its destructor called, the object is deleted both pointers are now undefined
16
Pass an object to a function
void f(withDestructor destination) { // Same problem on assignment destination = source; // Two pointers are pointing to the same memory } int main() { withDestructor source("The source's memory"); f(source); cout << "Does this statement execute?" << endl; return 0;
17
When f is done The pointer to characters is memberwise copied to the function f When f is done, the memory pointed to by two pointers is deleted When control goes back to main, source is bad
18
What happens then Many bad things can happen when an object with a pointer data member is passed to a function or assigned to another object 'Null pointer assignment', 'Segmentation fault', 'General Protection Fault', Some system-dependent behavior, which may be intermittent
19
Use Copy Constructors Any class with a pointer data member should have
an overloaded assignment operator (Ch 18) a copy constructor (this section) General form: Copy constructor class-name ( const class-name & parameter-name ) ; The copy constructor gets called when you pass an object to a value parameter you have to write the copy constructor to allocate new memory for the function
20
class WithDestructor copy onstructor
One possible copy constructor for class withDestructor allocates new memory and copies the data withDestructor:: withDestructor(const withDestructor& source) { // This copy constructor allocates new memory for s s = new char[strlen(source.s) + 1]; // and copies all characters into that new memory strcpy(s, source.s); // This is different from s = source.s; // which would copy an address and leave two // pointer data members pointing to the same memory }
21
Another example The string copy constructor (in ltstring.cpp)
allocate new memory, copy all chars, not a pointer string::string(const char * source) { // Actual length without '\0' my_len = strlen(source); // Allocate memory for '\0' my_chars = new char[my_len + 1]; // Let my_chars point to initText strcpy(my_chars, source); }
22
Just do it C++ classes with pointer objects and dynamic memory allocation must add a copy constructor, a destructor, and an overloaded assignment operator see Chapter 18, "Operator Overloading"
23
15.6 Linked Lists (and the C struct)
store a collection of objects in a sequential fashion are used to maintain just enough memory when needed at the risk of slowing down the program incidentally have a collection of structs to store may elements containing the data a special data member called the link field
24
Structs A struct is almost exactly like a class
one difference: default access mode is public but if you always use public: and private:, there is no difference historically, the struct is considered a way to hold data where the data members are accessible you access the data without using member functions when used with linked lists, structs have a data field that can point to another struct of the same type
25
Example struct definition
// Define the type of data stored in each node typedef string Type; struct node { //--constructors node(); node(Type data); // Two public data members Type my_data; node* next; // I can point to myself! };
26
The member functions // Both constructors set next to point to nothing, // which is also known as NULL node::node() { next = NULL; } node::node(Type data) my_data = data;
27
Hard code a linked list A linked list is a collection of objects with the attribute that one object can be reached from another through a pointer Hard code a linked list of three nodes: // Build the first node node* p = new node("First"); // Construct a second node pointed to by // the first node's next p->next = new node("Second"); // Build a third node pointed to by p->next->next p->next->next = new node("Third");
28
A linked list with 3 nodes
You end up with a linked list of three objects What is the value of p->next->next->next ? What is the output? for(node* temp=p; temp != NULL; temp=temp->next) cout << temp->my_data << endl;
29
15.6.1 A Simple Linked List Class
This section shows how to store a collection of object--a list it uses a linked structure rather than an array it has an iterator pattern that does not let you know if the elements are stored in an array or in a linked structure, or in a file, or .... now the currentItem member function returns a pointer to the object in the list very useful for finding objects and changing them while they remain in the list
30
Example usage first LinkedList aList; // Yes--starts with upper case L
aList.append("Tommy"); aList.append("Didi Fickle"); aList.append("Chuckie"); aList.append("Zirconium Lil"); // Iterate over all elements listElementType* p; for(aList.first(); !aList.isDone(); aList.next() ) { p = &aList.currentItem(); // Do whatever you want to do with the object // in the list. Reference it with *p // This could be a bankAccount or employee, or... }
31
The class definition // File name: llist.h
// Define the struct needed by the LinkedList class struct node { public: //--constructors node(); node(listElementType data); // Public data (by default) listElementType my_data; node* structs_next; };
32
Member functions of LinkedList
class LinkedList { public: LinkedList(); void append(const listElementType& newElement); // List == List with newElement added at the end bool remove(const listElementType& removalElement); // pre: The listElementType defines == // post: removalElement removed if found int size() const; // Number of elements currently stored in the list
33
The iterator member functions
void first() const; // post: my_index points to the first item, or if this // is empty, isDone would now return true void next() const; // post: my_index points to next item, or isDone is true bool isDone() const; // post: true if the collection has been traversed listElementType& currentItem(); // pre: ! isDone && my_size > 0 // post: Return address of item pointed to by my_index const listElementType& currentItem() const;
34
The member functions This linked list uses pointers to point to dummy head node This makes it easier to implement the functions They are called my_first and my_last here Here is an empty list based on code in the constructor my_first = new node; my_last = my_first;
35
Appending to a list unordered
Appending (adding an element at the end) is easy when there is no order to the list void LinkedList::append(const listElementType& newElement) { // Allocate and initialize a new node my_last->structs_next = new node(newElement); // Update the last pointer my_last = my_last->structs_next; // update current size my_size++; }
36
LinkedList::remove An object is in the list or it is not
remove traverses the list until it is found or the end of the linked list is reached start like this follow code on pages
37
Let prev trail current Advance pointers until found or not
prev trails current until end of list or until found Watch for special case of deleting the last node could be fixed with a dummy trailer node
38
Remove "second" If we were trying to remove Second
move prev->next to point to what the about to be removed node was pointing to then you can delete current
39
No dummy trailer node Because there is no dummy trailer node, removing the last node must be considered a special case if(current == NULL) // removalElement was not found return false; else { // Take out the element prev->structs_next = current->structs_next; if(current == my_last) // Removing the last node is a my_last = prev; // special case. delete current; my_size--; // Maintain current size return true; }
40
Why is last not a dummy node?
Without an append member function, there would likely be a different implement Also, if this were meant to be an ordered list, it would be better to have a dummy last node in addition to a dummy first node
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.