Data Structures Exam 1 - Chapter 4

Réussis tes devoirs et examens dès maintenant avec Quizwiz!

What does fileExtension point to after the following code? const char* fileName = "Sample.file.name.txt"; const char* fileExtension = strrchr(fileName, '.'); + ".file.name.txt" + ".txt" + "Sample.file.name"

".txt" strrchr() returns a pointer to the last '.' character in the string, which is the '.' before the "txt".

pointers

A pointer is a variable that holds a memory address, rather than holding data like most variables. A pointer has a data type, and the data type determines what type of address is held in the pointer. Ex: An integer pointer holds a memory address of an integer, and a double pointer holds an address of a double. A pointer is declared by including * before the pointer's name. Ex: int* maxItemPointer declares an integer pointer named maxItemPointer.

What does the code output? letterPointer = &userLetter; userLetter = 'A'; *letterPointer = 'C'; cout << userLetter; + A + B + C

C letterPointer points to userLetter, so changing *letterPointer to 'C' also changes userLetter to 'C'

What is the underlying structure of strings in C++? What do <string> member functions operate on?

Each string library function operates on one or more strings, each passed as a char* or const char* argument. Strings passed as char* can be modified by the function, whereas strings passed as const char* arguments cannot. Examples of such functions are strcmp() and strcpy()

(T/F) A variable declared as const char* firstMonth = "January"; could be passed as either argument to strcpy().

False firstMonth is a const char* and thus cannot be modified. Therefore, firstMonth can only be passed as a const char* argument, but not a char* argument.

(T/F) If an object with an int* sub-object is passed by value to a function, the program will call the class constructor to create a local copy of the sub-object.

False Passing an object by value creates a local copy of the object, but not by calling the constructor, which would make a new object. The local copy's sub-object points to the same memory location as the original object's sub-object, causing problems when the function terminates.

How can the copy constructor be called?

The copy constructor can be called with a single pass-by-reference argument of the class type, representing an original object to be copied to the newly-created object. A programmer may define a copy constructor, typically having the form: MyClass(const MyClass& origObject);

new operator

The new operator allocates memory for the given type and returns a pointer to the allocated memory. If the type is a class, the new operator calls the class's constructor after allocating memory for the class's member variables.

memory regions - the heap

The region where the "new" operator allocates memory, and where the "delete" operator deallocates memory. The region is also called free store.

(T/F) The code below outputs 3. int numSides = 3; int* valPointer = &numSides; PrintValue(valPointer);

True The variable numSides is initialized with a value of 3. valPointer is initialized with the reference to numSides. valPointer thus points to the same memory address. Printing the value of valPointer prints the value of the. memory address that numSides and valPointer point to, which is 3.

listToDisplay's destructor is called at the end of the DisplayList function. void DisplayList(LinkedList listToDisplay) { LinkedListNode* node = listToDisplay.head; while(node) { cout << node->data << " "; node = node->next; } }

True listToDisplay is not passed by pointer or by reference and goes out of scope at the end of the DisplayList function. Thus, listToDisplay's destructor is called.

reference operator &

Typically, a pointer is initialized with another variable's address. The reference operator obtains a variable's address. When a pointer is initialized with another variable's address, the pointer "points to" the variable

Why do we need a copy constructor?

because if we pass an object by value (rather than by reference), it creates a local copy, which can create errors. Using a copy constructor mitigates some of this risk

shallow copy

copy made without a copy constructor a copy made using assignment

What code properly frees the dynamically allocated array below? Airplane* airplanes = new Airplane[10]; + delete airplanes; + delete[] airplanes; + for(int i = 0; i < 10; i++) { delete airplanes[i];}

delete[] airplanes; When an array is dynamically allocated memory using the new operator, the memory must be deallocated using the delete[] operator

Pointer practice Declare a double pointer called sensorPointer

double* sensorPointer; the asterisk * must be placed next to the variable name to make the variable a pointer

Assuming char* firstQuit; is already declared, store in firstQuit a pointer to the first instance of "quit" in the char* variable userInput

firstQuit = strstr(userInput, "quit"); strstr() returns a pointer to the first instance of "quit" in userInput

Assuming char* firstR; is already declared, store in firstR a pointer to the first instance of an 'r' in the char* variable userInput

firstR = strchr(userInput, 'r'); strchr() returns a pointer to the first instance of an 'r' in userInput

Assuming char* lastR; is already declared, store in lastR a pointer to the last instance of an 'r' in the char* variable userInput

lastR = strrchr(userInput,'r'); strrchr() returns a pointer to the last instance of an 'r' in userInput

memory leak

occurs when a program that allocates memory loses the ability to access the allocated memory, typically due to failure to properly destroy/free dynamically allocated memory. A common error is failing to free allocated memory that is no longer used, resulting in a memory leak.

Refer to the code below. char userLetter = 'B'; char* letterPointer; What line of code assigns the variable outputLetter with the value letterPointer points to? outputLetter = letterPointer; outputLetter = *letterPointer; someChar = &letterPointer;

outputLetter = *letterPointer; The dereference operator * gets the value letterPointer points to. If letterPointer points to userLetter, then outputLetter is now 'B'

Which statement calls point1's Print() member function? Point point1(20, 30); + (*point1).Print(); + point1->Print(); + point1.Print();

point1.Print(); This one is tricky! point1 is not a pointer, so attempting to dereference or use the -> operator causes a compiler error

Which statement calls point2's Print() member function? Point* point2 = new Point(16, 8); + point2.Print(); + point2->Print();

point2->Print(); point2 is a pointer, so the -> operator is used to access the Print() member function

Which statement is not valid for multiplying point3's X and Y members? Point* point3 = new Point(100, 50); + point3->X * point3->Y + point3->X * (*point3).Y + point3->X (*point3).Y

point3->X (*point3).Y point3 is dereferenced with the * operator, but an additional * is needed to multiply the numbers

What is the purpose of a list's head node? + stores the first item in the list + provides a pointer to the first item's node in the list, if such an item exists + stores all the data of the list

provides a pointer to the first item's node in the list, if such an item exists The head points to the first item's node, or points to nothing if the list is empty.

Indicate if each code segment has a syntax error, runtime error, or no error. char* newPointer; *newPointer = 'A'; cout << *newPointer;

runtime error newPointer contains an unknown address when declared and is not initialized. Dereferencing an uninitialized pointer may cause the program to crash.

Indicate if each code segment has a syntax error, runtime error, or no error. char* newPointer = nullptr; char someChar = 'A'; *newPointer = 'B';

runtime error newPointer is initialized with nullptr when dereferenced and assigned 'B'. Dereferencing a null pointer causes the program to crash.

Pointer practice Assign sensorPointer with the variable sensorVal's address. In other words, make sensorPointer point to sensorVal sensorPointer = &sensorVal;

sensorPointer = &sensorVal; The reference operator & obtains a variable's address.

What is the behavior of default constructors, destructors, and assignment operators

If the programmer doesn't define a destructor for a class, the compiler implicitly defines one having no statements, meaning the destructor does nothing. If the programmer doesn't define a copy constructor for a class, then the compiler implicitly defines one whose statements do a memberwise copy, i.e., classObject2.memberVal1 = classObject1.memberVal1, classObject2.memberVal2 = classObject1.memberVal2, etc. If the programmer doesn't define a copy assignment operator, the compiler implicitly defines one that does a memberwise copy.

unusable memory

Memory locations that have been dynamically allocated but can no longer be used by a program. Unusable memory is created when a memory leak occurs.

rule of three

The rule of three describes a practice that if a programmer explicitly defines any one of those three special member functions (destructor, copy constructor, copy assignment operator), then the programmer should explicitly define all three. For this reason, those three special member functions are sometimes called the big three.

How many elements must be shifted? Assume no new memory needs to be allocated. Questions are for vectors, but also apply to arrays. Delete an item from the front of a 999-element vector.

998 After the first item is deleted, 998 elements remain. Each must be shifted, in order to fill the gap of the deleted item.

A linked list has what key advantage over a sequential storage approach like an array or vector? + An item can be inserted somewhere in the middle of the list without having to shift subsequent items + Uses less memory overall + Can store items other than int variables

An item can be inserted somewhere in the middle of the list without having to shift subsequent items Inserting only requires a couple of pointer updates

(T/F) When used with objects with pointer members, the default assignment operator behavior may lead to memory leaks.

True

(T/F) If a programmer explicitly defines a destructor, copy constructor, or copy assignment operator, it is a good practice to define all three.

True A good practice, known as the rule of three, is if a programmer explicitly defines any one of those three special member functions (destructor, copy constructor, copy assignment operator), then the programmer should probably explicitly define all three.

(T/F) Assuming MyClass prevObject has already been declared, the following variable declaration will call the copy assignment operator. MyClass object2; ... object2 = prevObject;

True An assignment from one existing object to another existing object will call the copy assignment operator.

(T/F) A character array variable declared as char myString[50]; can be passed as either argument to strcpy().

True When used as a function argument, myString behaves like a char* that points to the beginning of the 50-character array. So myString can be passed as a char* or const char* argument, and thus can be either argument to strcpy().

(T/F) The default assignment operator often works for objects without pointer members

True A memberwise assignment of basic types like float and int does not cause a problem. Pointer members are usually the source of problems.

(T/F) When used with objects with pointer members, the default assignment operator behavior may lead to crashes due to the same memory being freed more than once.

True As shown in the example above, two MyClass objects' dataObject pointers pointed to the same memory. Destruction of classObject1 freed the memory, then destruction of classObject2 tried to free the same memory again, causing a crash.

Given the following class declaration and variable declaration, determine which constructor will be called for each of the following statements. class EncBlock { public: EncBlock(); // Default constructor EncBlock(const EncBlock& origObj); // Copy constructor EncBlock(int blockSize); // Constructor with int parameter ~EncBlock(); // Destructor ... }; EncBlock myBlock; EncBlock* aBlock = new EncBlock(5); +EncBlock(); + EncBlock(const EncBlock& origObj); + EncBlock(int blockSize);

EndBlock(int blockSize); Constructor with int parameter is called because EncBlock(5) passes a single integer value to the constructor.

(T/F) Assuming MyClass prevObject has already been declared, the statement MyClass object2 = prevObject; will call the copy assignment operator.

False A class's copy constructor, not copy assignment operator, will be called when an object is initialized by copying another object during declaration.

(T/F) If the programmer does not explicitly define a copy constructor for a class, copying objects of that class will not be possible.

False If the programmer doesn't define a copy constructor for a class, then the compiler automatically defines one that performs a memberwise copy.

default assignment behavior

Given two MyClass objects, classObj1 and classObj2, a programmer might write classObj2 = classObj1; to copy classObj1 to classObj2. The default behavior of the assignment operator (=) for classes or structs is to perform memberwise assignment. Ex: classObj2.memberVal1 = classObj1.memberVal1; classObj2.memberVal2 = classObj1.memberVal2; ... Such behavior may work fine for members with basic types like int or char, but typically is not the desired behavior for a pointer member. Memberwise assignment of pointers may lead to program crashes or memory leaks.

Classes have what three special member functions? They are commonly implemented together

Destructor: A destructor is a class member function that is automatically called when an object of the class is destroyed, such as when the object goes out of scope or is explicitly destroyed as in delete someObject;. Copy constructor: A copy constructor is another version of a constructor that can be called with a single pass by reference argument. The copy constructor is automatically called when an object is passed by value to a function, such as for the function SomeFunction(MyClass localObject) and the call SomeFunction(anotherObject), when an object is initialized when declared such as MyClass classObject1 = classObject2;, or when an object is initialized when allocated via "new" as in newObjectPtr = new MyClass(classObject2); Copy assignment operator: The assignment operator "=" can be overloaded for a class via a member function, known as the copy assignment operator, that overloads the built-in function "operator=", the member function having a reference parameter of the class type and returning a reference to the class type.

Given the following class declaration and variable declaration, determine which constructor will be called for each of the following statements. class EncBlock { public: EncBlock(); // Default constructor EncBlock(const EncBlock& origObj); // Copy constructor EncBlock(int blockSize); // Constructor with int parameter ~EncBlock(); // Destructor ... }; EncBlock myBlock; EncBlock testBlock; + EncBlock(); + EncBlock(const EncBloc& origObj); + EncBlock(int blockSize);

EncBlock(); The default constructor is called because no arguments are passed to the constructor.

Given the following class declaration and variable declaration, determine which constructor will be called for each of the following statements. class EncBlock { public: EncBlock(); // Default constructor EncBlock(const EncBlock& origObj); // Copy constructor EncBlock(int blockSize); // Constructor with int parameter ~EncBlock(); // Destructor ... }; EncBlock myBlock; EncBlock* lastBlock = new EncBlock(myBlock); + EncBlock(); + EncBlock(const EncBlock& origObj); + EncBlock(int blockSize);

EncBlock(const EncBlock& origObj); The copy constructor is explicitly called because a variable of the same class type is passed to the constructor.

Given the following class declaration and variable declaration, determine which constructor will be called for each of the following statements. class EncBlock { public: EncBlock(); // Default constructor EncBlock(const EncBlock& origObj); // Copy constructor EncBlock(int blockSize); // Constructor with int parameter ~EncBlock(); // Destructor ... }; EncBlock myBlock; EncBlock vidBlock = myBlock; + EncBlock(); + EncBlock(const EncBlock& origObj); + EncBlock(int blockSize);

EncBlock(const EncBlock& origObj); The copy constructor is implicitly called with myBlock because a variable is initialized during the variable declaration to an existing variable of the same class type.

destructor

a special class member function that is called automatically when a variable of that class type is destroyed. C++ class objects commonly use dynamically allocated data that is deallocated by the class's destructor.

Declare a copy assignment operator for a class named EngineMap using inVal as the input parameter name. EngineMap& operator=( ______________________________);

const EngineMap& inVal The statement declares a copy assignment operator for a class named EngineMap using inVal as the input parameter name

Refer to the code below. char userLetter = 'B'; char* letterPointer; What line of code makes letterPointer point to userLetter? letterPointer = userLetter; *letterPointer = &userLetter; letterPointer = &userLetter;

letterPointer = &userLetter; letterPointer is assigned with the address of userLetter by using the reference operator &

Provide the return statement for a copy assignment operator

return *this; The statement return *this dereferences the 'this' pointer for the object being assigned, returning the object itself

Common string functions strchr()

strchr(sourceStr, searchChar) Returns a null pointer if searchChar does not exist in sourceStr. Else, returns pointer to first occurrence.

Common string functions strrchr()

strrchr(sourceStr, searchChar) Returns a null pointer if searchChar does not exist in sourceStr. Else, returns pointer to LAST occurrence (searches in reverse, hence middle 'r' in name).

Common string functions strstr()

strstr(str1, str2) Returns a null pointer if str2 does not exist in str1. Else, returns a char pointer pointing to first occurrence of string str2 within string str1.

Indicate if each code segment has a syntax error, runtime error, or no error. char someChar = 'Z'; char* valPointer; *valPointer = &someChar;

syntax error char someChar = 'Z'; char* valPointer; *valPointer = &someChar; A pointer cannot be assigned with an address when using the dereference operator *. The correct way to assign valPointer: valPointer = &someChar;

constructor arguments - new operator

the new operator can pass arguments to the constructor. The arguments must be in parentheses following the class name.

Overloading the assignment operator - copy

The assignment operator (=) can be overloaded to eliminate problems caused by a memberwise assignment during an object copy. The implementation of the assignment operator iterates through each member of the source object. Each non-pointer member is copied directly from source member to destination member. For each pointer member, new memory is allocated, the source's referenced data is copied to the new memory, and a pointer to the new member is assigned as the destination member. Allocating and copying data for pointer members is known as a deep copy.

(T/F) The big three member functions for classes include a destructor, copy constructor, and default constructor.

The big three member functions for classes include a destructor, copy constructor, and copy assignment operator.

linked list

A linked list consists of items that contain both data and a pointer—a link—to the next list item.

pointer

A pointer is a variable that contains a memory address.

Finding the 500th item in a 999-item linked list requires visiting how many items? Correct answer is one of 0, 1, 500, and 999.

500 The program starts at the 1st item, follows that item's pointer to the 2nd item, follows that item's pointer to the 3rd item, ..., until reaching the 500th item. The inability to immediately access any data item is a drawback of linked lists.

Pointer practice Output the address of the double variable sensorVal cout << ___________;

&sensorVal Need to use the reference operator '&' to obtain a variable's address

How many elements must be shifted? Assume no new memory needs to be allocated. Questions are for vectors, but also apply to arrays. Inserting a new item between the 10th and 11th items of a 999-item linked list

0 no shifting is required, just changes to the value of the pointers

How many elements must be shifted? Assume no new memory needs to be allocated. Questions are for vectors, but also apply to arrays. Delete an item from the end of a 999-element vector

0 Deleting from the end just removes the item from the end. No gap is created in the middle of the vector, so no shifting is needed.

How many elements must be shifted? Assume no new memory needs to be allocated. Questions are for vectors, but also apply to arrays. Appending an item at the end of a 999-item linked list

0 the new item is simply added to the end

How many elements must be shifted? Assume no new memory needs to be allocated. Questions are for vectors, but also apply to arrays. Append an item to the end of a 999-element vector (e.g., using push_back()).

0 Appending just places the new item at the end of the vector. No shifting of existing elements is necessary

How many elements must be shifted? Assume no new memory needs to be allocated. Questions are for vectors, but also apply to arrays. Insert an item at the front of a 999-element vector.

999 Inserting at the front requires making room for the new element. So every current element must be shifted once.

list node - class definition example

A class is defined to represent each list item, known as a list node. A node is comprised of the data to be stored in each list item, in this case just one int, and a pointer to the next node in the list. A special node named head is created to represent the front of the list, after which regular items can be inserted.

What are some common pointer runtime errors?

A common error is to use the dereference operator when a pointer has not been initialized. Ex: cout << *valPointer; may cause a program to crash if valPointer holds an unknown address or an address the program is not allowed to access. A common error is to dereference a null pointer. Ex: If valPointer is null, then cout << *valPointer; causes the program to crash. A pointer should always hold a valid address before the pointer is dereferenced.

What are some common pointer syntax errors?

A common error is to use the dereference operator when initializing a pointer. Ex: *valPointer = &maxValue; is a syntax error because *valPointer is referring to the value pointed to, not the pointer itself. A common error when declaring multiple pointers on the same line is to forget the * before each pointer name. Ex: int* valPointer1, valPointer2; declares valPointer1 as a pointer, but valPointer2 is declared as an integer because no * exists before valPointer2. Good practice is to declare one pointer per line to avoid accidentally declaring a pointer incorrectly.

Inserting/erasing in vectors vs. linked lists vector insert/erase performance problem

A vector (or array) stores a list of items in contiguous memory locations, which enables immediate access to any element of a vector userGrades by using userGrades.at(i) (or userGrades[i]). However, inserting an item requires making room by shifting higher-indexed items. Similarly, erasing an item requires shifting higher-indexed items to fill the gap. Shifting each item requires a few operations. If a program has a vector with thousands of elements, a single call to insert() or erase() can require thousands of instructions and cause the program to run very slowly, often called the vector insert/erase performance problem.

destructors - memory

Destructors are needed when destroying an object involves more work than simply freeing the object's memory. Such a need commonly arises when an object's data member, referred to as a sub-object, has allocated additional memory. Freeing the object's memory without also freeing the sub-object's memory results in a problem where the sub-object's memory is still allocated, but inaccessible, and thus can't be used again by the program.

(T/F) strstr(fileName, ".pdf") is non-null only if the fileName string ends with ".pdf".

False Ex: If fileName is "Not.a.pdf.file.txt", strstr(fileName, ".pdf") returns a non-null pointer, even though the string doesn't end with ".pdf".

(T/F) When a dynamically allocated array increases capacity, the array's memory location remains the same

False When an array runs out of memory slots for new elements, the array copies all elements to new memory locations. The pointer that points to the array's starting location then moves to point to the new starting memory location.

(T/F) A variable declared as char* substringAt5 = &myString[5]; cannot be passed as an argument to strcmp(), since strcmp() requires const char* arguments.

False A char* can be passed as a const char* argument. The const just implies that the string will not be modified by the function.

(T/F) If list1 were declared without dynamic allocation, as shown below, no destructor would be needed LinkedList list1;

False Even if the list itself isn't dynamically allocated, the list's nodes are. A destructor is still needed to free each node in the list.

(T/F) Using the delete operator to deallocate a LinkedList object automatically frees all nodes allocated by that object

False The LinkedList object's nodes are not freed automatically. A destructor must be implemented to free each node in the list

(T/F) After the statement delete point1; executes, point1 will be null

False The delete operator deallocates memory that point1 points to but does not set point1 to null

(T/F) The statement delete point1; throws an exception if point1 is null

False The delete operator does not throw an exception if the pointer is null. Deleting a null pointer is a special case in which the delete operator does nothing.

(T/F) When used with a class type, the new operator allocates memory after calling the class's constructor.

False The new operator allocates memory before, not after, calling the class's constructor

(T/F) The new operator returns an int

False The new operator returns a pointer to allocated memory, not an int

(T/F) The code below outputs 7. int numSides = 7; int* valPointer = nullptr; cout << *valPointer;

False The output statement dereferences valPointer, which is null. dereferencing a null pointer causes the program to crash

(T/F) The delete operator can affect any pointer.

False The pointer must point to memory allocated with the new operator

(T/F) listToDisplay's destructor is called at the end of the DisplayList function. void DisplayList(LinkedList& listToDisplay) { LinkedListNode* node = listToDisplay.head; while(node) { cout << node->data << " "; node = node->next; } }

False Because it passed as a reference listToDisplay is passed by reference, so the destructor is not called at the end of the DisplayList function.

(T/F) If an object with an int* sub-object is passed by value to a function, the program will complete execution with no errors

False When passed by value to a function, a local copy of the object is made, which directs a copy of the int* sub-object to point at the same data as the original object. When the function terminates, the destructor destroys the local object, freeing the sub-object's memory. When main() terminates, the destructor is called again to free the already freed memory, causing a crash.

(T/F) The code below outputs 5. int numSides = 5; int* valPointer = &numSides; valPointer = nullptr; PrintValue(valPointer);

False valPointer points to numSides initially, but then is assigned nullptr.

(T/F) The size of a vector is the same as the vector's capacity

False - memory is dynamically allocated, so the size is just the current number of elements in the vector

What happens if a programmer does not define a copy constrcutor?

If the programmer doesn't define a copy constructor, then the compiler implicitly defines a constructor with statements that perform a memberwise copy, which simply copies each member using assignment: newObj.member1 = origObj.member1, newObj.member2 = origObj.member2, etc. Creating a copy of an object by copying only the data members' values creates a shallow copy of the object. A shallow copy is fine for many classes, but typically a deep copy is desired for objects that have data members pointing to dynamically allocated memory.

(Y/N) Does the scenario result in a memory leak? int main() { MyClass* ptrOne = new MyClass; MyClass* ptrTwo = new MyClass; MyClass* ptrThree; ptrThree = ptrOne; ptrOne = ptrTwo; return 0; }

No Pointing ptrThree to ptrOne's object before re-pointing ptrOne keeps track of both MyClass objects. ptrOne and ptrThree point at the first MyClass object before ptrOne is set to point elsewhere.

(Y/N) Does the scenario result in a memory leak? class MyClass { public: MyClass() { subObject = new int; *subObject = 0; } ~MyClass() { delete subObject; } private: int* subObject; }; int main() { MyClass* ptrOne = new MyClass; MyClass* ptrTwo = new MyClass; ... delete ptrOne; ptrOne = ptrTwo; return 0; }

No delete ptrOne causes the MyClass destructor to delete the MyClass sub-object, so memory for the object and sub-object are both freed before ptrOne is reassigned.

garbage collection

Some programming languages, such as Java, use a mechanism called garbage collection wherein a program's executable includes automatic behavior that at various intervals finds all unreachable allocated memory locations (e.g., by comparing all reachable memory with all previously-allocated memory), and automatically frees such unreachable memory.

What is true about fileName if the following expression evaluates to true? strchr(fileName, '.') == strrchr(fileName, '.') + The '.' character occurs exactly once in fileName + The '.' character occurs 0 or 1 time in fileName + The '.' character occurs 1 or more times in fileName

The '.' character occurs 0 or 1 time in fileName If fileName does not contain a '.', both strchr() and strrchr() return a null pointer. If '.' occurs once, the first and last occurrence pointers are the same.

dynamically allocated array

The C++ vector class is a container that internally uses a dynamically allocated array, an array whose size can change during runtime. When a vector is created, the vector class internally dynamically allocates an array with an initial size, such as the size specified in the constructor. If the number of elements added to the vector exceeds the capacity of the current internal array, the vector class will dynamically allocate a new array with an increased size, and the contents of the array are copied into the new larger array. Each time the internal array is dynamically allocated, the array's location in memory will change. Thus, the vector class uses a pointer variable to store the memory location of the internal array.

the delete operator

The delete operator deallocates (or frees) a block of memory that was allocated with the new operator. The statement delete pointerVariable; deallocates a memory block pointed to by pointerVariable. If pointerVariable is null, delete has no effect. After the delete, the program should not attempt to dereference pointerVariable since pointerVariable points to a memory location that is no longer allocated for use by pointerVariable. Dereferencing a pointer whose memory has been deallocated is a common error and may cause strange program behavior that is difficult to debug.

dereference operator (*)

The dereference operator (*) is prepended to a pointer variable's name to retrieve the data to which the pointer variable points. Ex: If valPointer points to a memory address containing the integer 123, then cout << *valPointer; dereferences valPointer and outputs 123.

How does a programmer allocate and delete object arrays

The new operator creates a dynamically allocated array of objects if the class name is followed by square brackets containing the array's length. A single, contiguous chunk of memory is allocated for the array, then the default constructor is called for each object in the array. A compiler error occurs if the class does not have a constructor that can take 0 arguments. The delete[] operator is used to free an array allocated with the new operator.

memory regions - the stack

The region where a function's local variables are allocated during a function call. A function call adds local variables to the stack, and a return removes them, like adding and removing dishes from a pile; hence the term "stack." Because this memory is automatically allocated and deallocated, it is also called automatic memory.

memory regions - static memory

The region where global variables (variables declared outside any function) as well as static local variables (variables declared inside functions starting with the keyword "static") are allocated. Static variables are allocated once and stay in the same memory location for the duration of a program's execution.

memory regions - code

The region where the program instructions are stored.

What is the syntax for implementing a LinkedList class destructor?

The syntax for a class's destructor function is similar to a class's constructor function, but with a "~" (called a "tilde" character) prepended to the function name. A destructor has no parameters and no return value. So the LinkedListNode and LinkedList class destructors are declared as ~LinkedListNode(); and ~LinkedList();, respectively

(T/F) The new operator allocates, but does not deallocate, memory

True The delete operator deallocates memory allocated with the new operator

(T/F) If an object with an int sub-object is passed by value to a function, the program will complete execution with no errors.

True When passed by value to a function, a local copy of the object is made, which also makes a local copy of the int sub-object. When the function terminates, both local objects are destroyed, causing no problems for the rest of the program. Common data types like int and double can be locally copied without a copy constructor.

(T/F) A destructor for the LinkedList class would be implemented as a LinkedList class member function

True A destructor is a special class member function.

(T/F) Both the constructor and the destructor are called by the following code: delete (new LinkedList());

True new LinkedList() allocates memory and calls the constructor. delete calls the destructor and deallocates the memory

(T/F) Data that is stored in memory and no longer being used should be deleted to free up that memory

True! Computers come with a finite amount of memory. If an array that is no longer used continues to take up memory, a memory leak could occur and eventually the computer could run out of usable memory (and crash). Unused allocated memory should be freed. Memory leaks are discussed in more detail elsewhere.

What happens when a destructor is called?

Using the delete operator on an object allocated with the new operator calls the destructor. For an object that is not declared by reference or by pointer, the object's destructor is called automatically when the object goes out of scope.

What is the syntax for pointers used to call class member functions?

When a class member function is called on an object, a pointer to the object is automatically passed to the member function as an implicit parameter called the this pointer. The this pointer enables access to an object's data members within the object's class member functions. A data member can be accessed using this and the member access operator for a pointer, ->,ex. this->sideLength. The this pointer clearly indicates that an object's data member is being accessed, which is needed if a member function's parameter has the same variable name as the data member.

member access operator - pointers

When using a pointer to an object, the member access operator (->) allows access to the object's members with the syntax a->b instead of (*a).b. Ex: If myPoint is a pointer to a Point object, myPoint->Print() calls the Print() member function.

(Y/N) does the scenario result in a memory leak? int main() { MyClass* ptrOne = new MyClass; MyClass* ptrTwo = new MyClass; ptrOne = ptrTwo; return 0; }

Yes ptrOne no longer points to the initial MyClass object, thus the object is inaccessible, causing a memory leak.

The statement below only works if the Dalmatian class has ______________. Dalmatian* dogs = new Dalmatian[101]; + no member functions + only numerical member variables + a constructor than can take 0 arguments

a constructor that can take 0 arguments The new operator must initialize each object in the array using a constructor that can take 0 arguments. A compiler error would occur if the Dalmatian class has no such constructor.

copy constructor

a constructor that is automatically called when an object of the class type is passed by value to a function and when an object is initialized by copying another object during declaration. The copy constructor makes a new copy of all data members (including pointers), known as a deep copy.

Assume the class FilmInfo has a private data member int filmLength and a member function void SetFilmLength(int filmLength). In SetFilmLength(), which would assign the data member filmLength with the value 120? + this->filmLength = 120; + this.filmLength = 120; + 120 = this->filmLength;

this->filmLength = 120; The 'this' pointer goes on the left side of the assignment statement '->' is the member access operator for pointers, and 'this' is a pointer referencing the current object

Assume the class FilmInfo has a private data member int filmLength and a member function void SetFilmLength(int filmLength). In SetFilmLength(), which would assign the data member filmLength with the parameter filmLength? filmLength = filmLength; this.filmLength = filmLength; this->filmLength = filmLength;

this->filmLength = filmLength; Part of the goal of the 'this' operator is to differentiate between the parameter and the data member object The this->filmLength refers to the FilmInfo object's data member.

Declare a char* variable named charPtr

char* charPtr;

null pointer

when a pointer is declared, the pointer variable holds an unknown address until the pointer is initialized. A programmer may wish to indicate that the pointer points to "nothing" by initializing the pointer to null. null means 'nothing' A pointer that is assigned with the keyword nullptr is said to be null. *maxPointerVal = nullptr; the pointer is now null

The array of points, when allocated using the new operator, _____ contiguous in memory + might or might not be + is always

is always This is how the new operator works with arrays the new operator always allocates an array as a contiguous block

Indicate if each code segment has a syntax error, runtime error, or no error. char* valPointer1, *valPointer2; valPointer1 = nullptr; valPointer2 = nullptr;

no errors both of the pointers are declared on the same line, but because they both have the * before the variable name, they are initialized correctly. They are both correctly assigned value as nullptr good practice is to initialize pointers on separate lines

deep copy

the type of copy that is created by a copy constructor it is a copy of all data members (including pointers)


Ensembles d'études connexes

Data Collection, Behavior, and Decisions

View Set

Chapter 10- Leadership, Managing and Delegation

View Set

Positioning Terminology - Chapter 1

View Set