Friday, September 21, 2007

STL vector and Some memory concerns.


I know STL vector is smart & very efficient . But when we using it lacks some memory deallocation functions other than destructor.
This is depending according to the version of Visual studio you are using . If you are using VS7 , the vector::clear() will remove all memory used by the vector. Otherwise , i mean if the compiler is VS2005 , you are in trouble. The vector hasn't any functions to release all memory used by it , except ~vector() (destructor).

Consider the following situations using VS2005

vector <int> myVec;
for(int i = 0 ; i < 10000; i++) myVec.push_back(i);
// ....some  codes.......

myVec.erase(myVec.begin()+1,myVec.end()); /*  removed all elements except the first.
                                                                     But memory still allocated , because vector
                                                                     reserved the memory for future allocations.*/

erase will mearly just removes  elements from the vector and calls destructor (->~_ty()). So still the memory is not deallocated(call myVec.capacity() to see the allocated bytes) .. What to do ? if you want to free up memory (Ofcourse u can delete , the last way).
One trick is to copy the contents to a new vector and again recopy it to the original vector , see below. Here the new vector(copy) will takes only the actual memory (it can be verifed using vector::capacity() ). During the recopy to original vector (myVec = copy) , the unwated memory is deleted.

Like

{

    vector<int> copy  = myVec;
    myVec  = copy.

}

So now the memory will be delted.. Ofcourse it makes some perfomance imacpt due to copy operation . But In some cases it can save a lot of memory . It depends upon the type of applcation.


Note : I have checked this only with Visaul Studio 7 , 8's  implementaion of STL.


Thursday, September 20, 2007

GetOpenFileName() And Some Deep crashes..

I think most of all windows programmers are familiar with GetOpenFileName() API (in MFC CFileDialog class).This api popups a open file dialog letting users to select the file they want.
Okay , I am going into the matter.
Try opening notepad.
1. click open from menu , now you can see open file dialog. Navigate to Desktop
2  move the mouse pointer around some file till tool tip visible.
3. Now cancel the dialog (press cancel or ESC)
4. Try to repeat the same thing (make sure again you go to desktop) , you will be awaited with a crash. Notepad disappears.


Interestingly This happens only with Desktop. I don't know why . So you might ask me how it mess up with the GetOpenFileName. Yes it relates , try calling GetOpenFileName in win32 App (not MFC). You can see the same behavior , your application crashes..


This is Bug in windows XP ( Service pack??? , any oher Version ??? ) .. i don't about any other versions.
If you debug the application you can't see any stack trace . This also happens with the GetSaveFileName api also.
For calling GetOpenFileName you need initialize COM , by calling CoInitialize(0) in the first of the program and call CoUnitinialize in the end of the program. Then it should work. The interesting thing is that in MSDN there is no information about this.


If you call like this as show below , still you can expect the crash.
CoInitialize(0);
GetOpenFileName();
CoUnitialize()

I don't know the exact reason . But my guess is that the GetOpenFileName() / SaveFileName() creats 4 threads .Even you close the dialog these thread exists ,  and these threads might call some com calls , after your CoUnitialize() . That may cause some problems. The most important this is that , There is a chance to crash every application ,  that uses GetOpenOpenFile/GetSaveFile dialog (and not initializing COM) . Seriously... 

Sunday, August 26, 2007

Type casting using Assembly code win32


We know that C++ will not allows assiging variable if they are on different typee. In That situations type casting is needed..But In some cases we can't use the c++ inbuilt type casting system as well as C style casting also..

 I am taking an exmaple of CreateThread thread proc function.(Beacuse many people uses static functions as the
thread proc for CreateThread.)

 For example if you look the function CreateThread API,the thread proc type is
DWORD WINAPI ThreadProc(void *lParam)
{

}

So this insist you to create some global functions or static functions.

Hence you can't pass your class member functions to CreateThread. So usually people will create some static functions and pass that function to CreateThread.And from inside that static function the appropriate class function is called..

This is fine. But using a littile asm code this can be avoided.
For example CCoffe is your class, and the MakeCoffe function we want to pass to CreateThread.  This can be done as below.

//sample codes
class CCoffe
{
  DWORD MakeCoffe(void *lParam)
  {
     return 0;
  }
}

//Initialization  function.
CCoffe::Init()
{  
   //temp is a function pointer of ThreadProc Type.
   DWORD (WINAPI*temp)(void*lp);
   __asm //Here we can pass any  address  to temp.      
   {


       mov EAX,CCoffe::MakeCoffe
       mov temp,EAX
   }
   //Call CreateThread with temp
   DWORD  out;
   CreateThread(0,0,temp,0,0,&out);
}

The Point is we can pass any address to temp,using asm block.Passing wrong function addresses 
may cause invalid stack structure,Might result in a crash.Hopes next time you will avoid static functions..

Note: I Don't know is this a good practice or not, If you have any opinion please let me know..