RSS .92| RSS 2.0| ATOM 0.3
  • Home
  • About
  •  

    Auto Pointers

    February 14th, 2010

    Pointers are still a nightmare for most of the C++ beginners. The confusion where to deallocate, deep copy or shallow copy results in memory leaks and occasional program crashes. A possible remedy to this is auto pointers.

    Image courtesy : http://www.usscouts.org
    

    Auto pointers provide some kind of automatic garbage collection. That means the programmer doesn’t have the headache of deleting the pointer, thereby ensuring that there won’t be memory leaks due to his carelessness.

    Unlike normal pointers, there can be only one owner for an auto pointer at a time, though ownership can be transferred.

    An auto pointer can be created using the syntax

    auto_ptr<T> variable name (new  T), where T is the class type to which the pointer belongs.

    An example is

    auto_ptr<int> myInt(new int(10));

    To transfer the ownership, we can simply assign the above to another auto_ptr variable.

    auto_ptr<int> myNewInt = myInt;

    In this case, myNewInt points to the location where 10 is stored and myInt = NULL:

    To assign an auto_ptr to a normal pointer, we can use the auto_ptr method release. Hence, the above functionality can be obtained in the following way also.

    int* myNormalInt = myInt.release();

    On calling release, the auto_ptr is set to NULL where as the memory location pointed by it is not destroyed, but assigned to the new variable.

    To access the memory location pointed by the auto_ptr variable, we can use the method get().

    A small example is described below.

    First we create a simple class

    
    // A simple class
    class CMyClass
    {
    public:
       // Constructor
       CMyClass(int no)
       :m_No(no)
       {
       }
       // Display the member variable
       void Display()
       {
          cout << "No is << " << m_No << "\n";
       }
    private:
       int m_No;
    };
    

    Now various operations using auto_ptr are shown below.

    
    #include "stdafx.h"
    #include <iostream>
    #include <memory>
    #include "assert.h"
    using namespace std;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
       // Create an auto_ptr
       auto_ptr<CMyClass> myClass(new CMyClass(10));
       // Assign the auto pointer to a new auto_ptr
       auto_ptr<CMyClass> myNewClass = myClass;
       // myClass will be NULL now
       assert(myClass.get() == NULL);
       // myNewClass now points to the location
       // where myClass pointed to
       myNewClass->Display();
       // myNewClass can be assigned to a normal
       // pointer as below
       CMyClass* myNormalClass = myNewClass.release();
       // myNewClass now points to NULL
       assert(myNewClass.get() == NULL);
       // myNormalClass now points to the location
       // myNewClass pointed to
       myNormalClass->Display();
       // Finally, we can delete myNormalClass.
       // Note that the auto_ptr variables do
       // not need deletion
       delete myNormalClass;
       myNormalClass = NULL;
       return 0;
    }
    

    How To Set Extra Data With Each Row Of A List Box

    February 3rd, 2009

    We can associate a 32 bit value with each row of a list box. The member function SetItemData() of CListBox can be used for this purpose.

    The syntax is

    int SetItemData(
       int nIndex,
       DWORD_PTR dwItemData
    );
    

    Parameters

    • nIndex – Zero based row index of the list box
    • dwItemData – 32 bit value to be stored in the row

    The return value will be LB_ERR, if an error occurs.
    The stored value can be retrieved using CListBox::GetItemData(). Again, the syntax is

    DWORD_PTR GetItemData(
       int nIndex
    ) const;
    

    where nIndex is the zero based index of the list box row, from where we have to get the data.

    An example is given below.

    for (int index = 0; index < myListBox->GetCount(); ++index)
    {
       if (myListBox->GetItemData(index) == DWORD(-1))
       {
          myListBox->SetItemData(index, 0);
       }
    }
    

    The header file afxwin.h is needed for the above functions.


    How To Watch A Variable Even After Its Scope Is Over

    January 19th, 2009

    Noramally, the value of a variable declared in a function can be seen in the watch window only when the control is inside that function itself (eg. When the above function calles a new function and if we step into the new function.) . Let’s discuss an example.

    void SomeFunction()
    {
       int myVariable = 20;
    }
    int main()
    {
       int myVariable = 10;
       SomeFunction();
       return 0;   
    }
    

    In the above example, if I put a break point in the function main after the statement int myVariable = 10; I can see the value of myVariable in the watch window as follows.

    break-point-in-main4

    Now, if I put another break point in SomeFunction() after the statement int myVariable = 20;, when th execution flow reaches there, the watch window will show the value of myariable as 20 only.

    So we have lost the value of myVariable declared in main(), eventhogh it lifetime is not over now.

    How To Add a Permanent watch

    We can still view the value of myVariable declared in main() inside the function SomeFunction(). For this, we will use the address of memory location (rather than the variable name) in which myVariable has been declared in main(). We can view the contents of this memory location as long as it has life in the program.

    When the control reaches the break point in main(), take the address of myVariable using the & operator. Now we have a valid memory location address (a pointer). Still, it can be a raw pointer. So cast it to the correct type (int, in this case, as myVariable is of type integer) as

    (int*)(address of myVariable)

    adding-a-watch1Now see how the watch window shows the value we have stored, when the control reaches the second break point.

    watching-the-old-variable1