Thread: Question regarding Memory Leak

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164
    I have read all the posts and I think that things have become a little confused as the thread grew. Here is some background on the original post:

    This is an online data structures class where I have the book to read and an obviously non-responsive instructor. My resources for the class are the textbook and you all (and google to a lesser degree).

    The textbook is: Data Structures using C++ by D. S. Malik. The question references the material covered in Chapter 3, Pointers and Array-Based Lists (Chapter One covered: Software Engineering Principles and C++ Classes, while Chapter Two covered: Object-Oriented Design(OOD) and C++). Chapter three sections prior to the quote below are Pointer Data Types and Pointer Variables; Dynamic Variables; Dynamic Arrays; Functions and Pointers; Shallow versus Deep Copy and Pointers; and now for the current section:
    “Classes and Pointers: Some Peculiarities.
    If a pointer variable is of a class type, we discussed, in the previous section, how to access class members via the pointer by using the arrow notation. Because a class can have pointer data members, this section describes some peculiarities of such classes. To facilitate the discussion, we use the following class:
    Code:
    	class pointerDataClass
    {
    public:
    		…
    private:
    		int x;
    		int lenP;
    		int *p;
    };
    Also consider the following statements:
    pointerDataClass objectOne;
    pointerDataClass objectTwo;

    Destructor.
    The object objectOne has a pointer data member p. Suppose that during program execution the pointer p creates a dynamic array. When objectOne goes out of scope, all data members of objectOne are destroyed. However p created a dynamic array, and dynamic memory must be deallocated using the operator delete. Therefore, if the pointer p does not use the delete operator to deallocate the dynamic array, the memory space of the dynamic array would stay marked as allocated, even though no one can access it. This is known as a ‘memory leak.’ How do we ensure that when p is destroyed, the dynamic memory created by p is also destroyed? Suppose that objectOne is as shown in fig3-16. (p points to an array outside the object loaded with integers {5, 36, 24, 15, …}
    Recall that if a class has a destructor, the destructor automatically executes whenever a class object goes out of scope. Therefore, we can put the necessary code in the destructor to ensure that when objectOne goes out of scope, the memory created by the pointer p is deallocated. This is one of the main purposes of including a destructor. For example, the definition of the destructor for the class pointerDataClass is:
    Code:
    	PointerDataClass::~pointerDataClass()
                 {
    	      delete [] p;
                  }
    Of course, you must include the destructor as a member of the class in its definition. Let us extend the definition of the class pointerDataClass by including the destructor. Moreover, the remainder of this section assumes that the definition of the destructor is as given previously – that is, the destructor deallocates the memory space pointed to by p.
    Code:
    	class pointerDataClass
    	{
    	public:
    		~pointerDataClass();
    		…
    	private:
    		int x;
    		int lenP;
    		int *p;
    	};
    NOTE: for the destructor to work properly, the pointer p must have a valid value. If p is not properly initialized (that is, if the value of p is garbage) and the destructor executes, either the program terminates with an error message or the destructor deallocates an unrelated memory space. For this reason, you should exercise caution while working with pointer.

    Assignment Operator:
    This section describes the limitations of the built-in assignment operators for classes with pointer data members. Suppose that objectOne and objectTwo are as shown in fig 3-17. (objectOne.x = 8, objectOne.lenP = 50, and objectOne.p points to an array of integers {5, 36, 24, 15, …} while objectTwo.x, objectTwo.lenP, and objectTwo.p are empty) Recall that one of the built-in operations on classes is the assignment operator. For example the statement:
    objectTwo = objectOne;
    copies the data members of objectOne into objectTwo. That is, the value of objectOne.x is copied into objectTwo.x, the value of objectOne.lenP is copied into objectTwo.lenP, and the value of objectOne.p is copied into objectTwo.p. Because p is a pointer, this member-wise copying of data would lead to a shallow copying of the data. That is, both objectTwo.p and objectOne.p would point to the same memory space, as shown in fig 3-18. (you all know what the picture looks like objectOne.p and objectTwo.p point to the same array) Now, if objectTwo.p deallocates the memory space to which it points, objectOne.p would become invalid. This situation could very well happen, if class pointerDataClass has a destructor that deallocates the memory space pointes to by p when an object of the type pointerDataClass goes out of scope. It suggests that there must be a way to avoid this pitfall. To avoid this shallow copying of data for classes with a pointer data member, C++ allows the programmer to extend the definition of the assignment operator. This process is called overloading the assignment operator. Once the assignment operator is properly overloaded, both the objects objectOne and objectTwo have their own data, as shown in fig 3-19. (again, you all know what the picture looks like – objectOne.p points to an array and objectTwo.p points to an array different than objectOne.p bet they are identical)”
    The next section is, Overloading the Assignment Operator (describes how to overload the assignment operator).

    SO, that is the information delivered on the topic in my one resource, and what I used to answer the question of this post as well as formulate my challenge to the test question.

    What I understand from the above quote out of the book is:
    With the shallow copy both pointers point to the same array so when one object goes out of scope, the memory allocated for the array is deallocated resulting in the second object pointer pointing to nothing. This is a problem, but the memory leak is the issue. The memory used by the array is available because it has been deallocated when one of the object pointers went out of scope. The assignment operator overload makes sure the two pointers each point to their own array (with their own allocated memory) so they don’t have to be concerned with what happens to the other object pointer.

    If I have things wrong please correct me, I don't mind getting one wuestion wrong, if I am wrong. But based on what I read, I don't see where a memory leak is prevented with an overloaded assignment operator included int eh class.

    Thanks for all the posts I have been educated.

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by clegs View Post
    If I have things wrong please correct me, I don't mind getting one wuestion wrong, if I am wrong. But based on what I read, I don't see where a memory leak is prevented with an overloaded assignment operator included int eh class.
    If you have objects A and B of the same type in this scenario and both A.ptr and B.ptr point to separate memory blocks, consider what happens if you do A = B;

    Here's what you have first:

    Code:
    A.ptr ---------> Block A
    B.ptr ---------> Block B
    Now after A = B, the shallow copy is done, and this occurs:

    Code:
                           Block A
    A.ptr -------------v 
    B.ptr ---------> Block B
    See the problem? Block A could be lost in the shallow copy.

    An overloaded assignment operator could be used to deallocate the memory of A.ptr before the assignment is done.

    However, as others have mentioned, this is NOT true for all cases, and this is why many of us voted for false (and CornedBee voted true but only because he said he felt he knew the intent of the question). If objects of this type are not responsible for the memory that their member pointers point to, then they should definitely NOT deallocate memory that isn't in their jurisdiction, at least if other parts of the program are relying on that memory to stay alive during assignments.

    To compare it to this example, if Block A needs to stay alive and is controlled by another object, then for A to delete it in the assignment would result in accessing a null pointer, and that could just be plain wrong.

  3. #3
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164
    Thanks MacGyver.
    I understand your example. That makes sense. I wish there was an example in the book like that. What I read in the book, which was the only information source I had - there wasn't an example of the pointers pointing to their own list before the copy - deep or shallow. They only had two pointers one pointing to an array and the other just declared. There wasn't any explanation of the example you gave where a pointer was already pointing to a list then the assignment happens for a copy (shallow or otherwise, right?) resulting in a memory leak when they were discussing destructors, assignments operator and memory leaks.

    I just reviewed the section that described how to overload the assignment operator which is the next section after what I posted above. They go into great detail on how to avoid a self copy and what code needs to be present to prevent this. And at the end they give a working example. The code block for the assignment operator in this example has two lines of code:
    if(list != NULL) //Line 2
    destroyList(); //Line 3
    list is a member and otherList is an const reference argument. The explanation following the example states: "The statement in line 2 checks whether list is nonempty. If it is nonempty, then list is destroyed by deallocating the memory occupied by list. ... If otherList is not NULL and not empty, the statements between line 6 and 10 (which I didn't include) create an array list and copy otherList into list." So, I guess that is what this question is referring to.
    I guess I will let this question go without challenge.

    Thanks for your explanation!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Assignment Operator, Memory and Scope
    By SevenThunders in forum C++ Programming
    Replies: 47
    Last Post: 03-31-2008, 06:22 AM
  2. Memory Leak Help
    By (TNT) in forum Windows Programming
    Replies: 3
    Last Post: 06-19-2006, 11:22 AM
  3. Memory Leak
    By Berticus in forum C++ Programming
    Replies: 5
    Last Post: 07-20-2005, 05:11 PM
  4. Memory Address of Array Question
    By Zeusbwr in forum C++ Programming
    Replies: 3
    Last Post: 10-24-2004, 09:58 AM
  5. Is it necessary to write a specific memory manager ?
    By Morglum in forum Game Programming
    Replies: 18
    Last Post: 07-01-2002, 01:41 PM