Wednesday, October 7, 2009

Pointer arguments and returns, a concept clarified

While working on my C++ project, I faced a stupid problem. It was the concept that I learned in my first two semesters of undergraduate studies but over time while working on different technologies the concept faded into my subconscious. It was about passing pointer as arguments and returning them, while we are assigning new memory to them within the method. I passed the pointer to a method, then allocated memory in the method and assigned it to the variable. After returning from method, the pointer value that I worked out within method was not available.

It was because I never rewrite the pointer variable with the new address. Just look at the sample codes and discussions below:


Sample 1:
void PointerArg::ArgIntUpdate(SamClass* _SamClassPtr)
{
_SamClassPtr = new SamClass();
_SamClassPtr->SetID(7);
_SamClassPtr->ShowMessage();
printf("");
printf(" : Address is : %X", _SamClassPtr);
}

printf("\n\nAddress before : %X", SamClassPtr);
this->ArgIntUpdate(SamClassPtr);
SamClassPtr->ShowMessage();
printf("");
printf(" : Address is : %X", SamClassPtr);

Sample 1 output:
Address before : 422BA0
ID is 7 : Address is : 422BE0
ID is 3 : Address is : 422BA0

Discussion
In sample 1, we pass pointer variable SamClassPtr as argument to method ArgIntUpdate. In ArgIntUpdate we assign the pointer variable with new address of newly allocated class object using new. When we return from this method, the original class level variable still points to old address, i.e., 422BA0 in our case.

Sample 2:
void PointerArg::ArgIntUpdateMalloc(SamClass* _SamClassPtr)
{
_SamClassPtr = (SamClass*)malloc(sizeof(SamClass));
_SamClassPtr->SetID(9);
_SamClassPtr->ShowMessage();
printf("");
printf(" : Address is : %X", _SamClassPtr);
}

printf("\n\nAddress before : %X", SamClassPtr);
this->ArgIntUpdateMalloc(SamClassPtr);
SamClassPtr->ShowMessage();
printf("");
printf(" : Address is : %X", SamClassPtr);

Sample 2 output:
Address before : 422BA0
ID is 9 : Address is : 422C20
ID is 3 : Address is : 422BA0

Discussion
In sample 2, we pass pointer variable SamClassPtr as argument to method ArgIntUpdateMalloc. In ArgIntUpdateMalloc we assign the pointer variable with new address of newly allocated class object using malloc. When we return from this method, the original class level variable still points to old address, i.e., 422BA0 in our case.

Sample 3:
SamClass* PointerArg::RetUpdate(void)
{
SamClass _SamClassObj;
_SamClassObj.SetID(11);
(&_SamClassObj)->ShowMessage();
printf("");
printf(" : Address is : %X", &_SamClassObj);
return &_SamClassObj;
}

printf("\n\nAddress before : %X", SamClassPtr);
SamClassPtr = this->RetUpdate();
SamClassPtr->ShowMessage();
printf("");
printf(" : Address is : %X", SamClassPtr);

Sample 3 output:
Address before : 422BA0
ID is 11 : Address is : 13FD50
ID is -858993460 : Address is : 13FD50

Discussion
In sample 3, we return a pointer variable SamClassPtr from method RetUpdate. In RetUpdate we assign the pointer variable with new address of newly allocated class object. When we return from this method, the original class level variable is overwritten with new address, i.e., 13FD50 in our case, however, since the object was allocated with in method it is no longer available after method is returned and we found garbage at the same location.

Sample 4:
SamClass* PointerArg::RetUpdateNew(void)
{
SamClass* _SamClassObj = new SamClass();
_SamClassObj->SetID(13);
_SamClassObj->ShowMessage();
printf("");
printf(" : Address is : %X", _SamClassObj);
return _SamClassObj;
}

printf("\n\nAddress before : %X", SamClassPtr);
SamClassPtr = this->RetUpdateNew();
SamClassPtr->ShowMessage();
printf("");
printf(" : Address is : %X", SamClassPtr);

Sample 4 output:
Address before : 13FD50
ID is 13 : Address is : 422C60
ID is 13 : Address is : 422C60

Discussion
In sample 4, we return a pointer variable SamClassPtr from method RetUpdateNew. In RetUpdateNew we assign the pointer variable with new address of newly allocated class object using new operator. When we return from this method, the original class level variable is overwritten with new address, i.e., 422C60 in our case, however, this time since the object was allocated using new it is still available at the same address after method is returned.

Sample 5:
SamClass* PointerArg::RetUpdateMalloc(void)
{
SamClass* _SamClassObj = (SamClass*)malloc(sizeof(SamClass));
_SamClassObj->SetID(15);
_SamClassObj->ShowMessage();
printf("");
printf(" : Address is : %X", _SamClassObj);
return _SamClassObj;
}

printf("\n\nAddress before : %X", SamClassPtr);
SamClassPtr = this->RetUpdateMalloc();
SamClassPtr->ShowMessage();
printf("");
printf(" : Address is : %X", SamClassPtr);

Sample 5 output:
Address before : 422C60
ID is 15 : Address is : 422CA0
ID is 15 : Address is : 422CA0

Discussion
In sample 5, we return a pointer variable SamClassPtr from method RetUpdateMalloc. In RetUpdateMalloc we assign the pointer variable with new address of newly allocated class object using malloc operator. When we return from this method, the original class level variable is overwritten with new address, i.e., 422CA0 in our case, however, this time since the object was allocated using malloc it is still available at the same address after method is returned.

Conclusions:
1) When passing the pointers by argument, make sure we assign it the memory before passing the variable and we are not overwrite the memory within method.

2) If we want to allocate new class object within method, we should make sure we do it using new or malloc instread of direct object instantiation. This will ensure that memory is still available after method is returned.

Wednesday, September 16, 2009

Writing research papers (Last minute check list)

 As researchers, we always have to keep in mind few important common checks that we verify while writing the research papers. I am listing few of my important findings here for researchers new to this field. I must start with the reference to the most useful link I found from Prof. Dr. Felix Nauman from Hasso-Plattner-Institut für Softwaresystemtechnik. The link is as follows:


http://www.hpi.uni-potsdam.de/naumann/mitarbeiter/felix_naumann/writing


He listed few important checks for research papers. I am getting benefit from this link on my every research paper. Now I list few of my personal experiences below:


    * Make sure you use et al. for only more then 2 authors paper
    * Term are abbreviated only on their first usage
    * Check for confused words

          o Then (Time), than (Comparison)
          o There (location, condition, situation), Their (possession)
          o etc.

    * Make sure first character is Capital for important terms like Information Systems
    * Check section numbering
    * Make sure all figures caption are sentence case
    * Make sure web links are working correctly (Beware of special characters)
    * Check bibtex for consistency

          o Use software’s like JabRef for managing bibtex

    * Proof read the text for articles

For any research paper, we should be able to answer following question:


(1) what is the general problem (area)?

(2) Why is it important?

(3) What specific problem (in the general area) are you working on?

(4) Why is its solution important?

(5) Why does solving the specific problem worthy of?


I got these questions from my colleague Sven, and he got them from one of his supervisors. I liked them and I try to answer them for each of my research deliverable.

Beware of silent array out of bound

I often face the problem of memory over-write. This problem occurs when i program with pressure of deadline, however this problem consumes much more time to diagnose. While working with my last code fragment i wasted many minutes just to figure out what is happening. I worked with a structure as follows:

#define TREEBLOCKWIDTH 2

struct inode{   
public:
    int keys[TREEBLOCKWIDTH];
    int refnodeids[TREEBLOCKWIDTH + 1];
    char* refnodenames[TREEBLOCKWIDTH + 1];
    unsigned int elements;
    bool isleaf;
};

Now in my code i come to know that i am updating a value in keys and the value is also changing in refnodeids. Now we look inside. The values in memory are as follows:

keys[0] keys[1] refnodeids[0] refnodeids[1] refnodenames[0] refnodenames[1] refnodenames[2] elements isleaf

Now try to access keys[2] and check what happens. Index 2 is out of bound for array keys, but C++ compiler will not complain for this, instead it will give you the value of refnodeids[0]. I like to call it silent array index out of bound because we are using the wrong index still code will execute and will make problem later on if left undiagnosed.

Tuesday, September 8, 2009

Attending DEXA 2009

Last week I was at Johannes Kepler University, Linz, Austria attending DEXA 2009 conference. I personally accepted this event as my first exposure to relatively well ranked conference. My expectations were quite high. My reported experiences here are my personal views and there is a huge possibility people might have different opinions.

DEXA as an event is really a large event with many researchers from diversified fields and cultures. Good thing was that I found a variety of talks and presentations to select from. Overall it was a well managed event.

Quality of research papers was really good but I will not say excellent. Attending audience in sessions was decreasing over day with too few people at the last day. So always wish for presentation in starting two days of conference to get good feedback.

The most painful experience for me was the session with missing presenters. Every conference event asks presenters to inform in advance about their attendance. It was really sad to observe the researchers having time slot for their presentations and not appear for it. I hope for better attitude from researchers towards informing about their absence in advance.

Invited talks were really interesting. Talks from Johann Eder, University of Klagenfurt, Austria "Data Management for Federated Biobanks" and Abdelkader Hameurlain, Paul Sabatier University, Toulouse, France "Evolution of Query Optimization Methods: from Centralized Database Systems to Data Grid Systems" were really nice. In all invited talks I was expecting the key note speakers to share their experiences. The lessons they learned that we don't find in books or on internet. However, most of the content was quite normal technical details.

I am quite a normal presenter but I only liked 10% of presentation in terms of the way they were presented. Too few speakers were able to take audience with them in flow. Most of the presenters dived into the ocean of technicalities leaving the audience to sink into it without proper equipment. I am not a good audience but I was only able to understand presentation with my technical background on those topics. Otherwise, I was unable to grasp the high level details of contributions from many presentations. The most interesting session for me was from DaWak 2009 with Jan Chmiel presenting HOBI: Hierarchically Organized Bitmap Index for Indexing Dimensional Data and Goetz Graefe presenting Fast loads and fast queries. These two were the best presentations of the event for me. Few more names are also their but I don't want to list them all here. The highest contribution was in the area of XML databases, I don't remember the count but it was the highest.

Overall DEXA was a really good conference but missing the touch to be called the excellent one.

Friday, August 28, 2009

CMake Error: Could not create named generator Visual Studio 8 2005

I engaged with this error while building the MySQL instance from source. The reason of this problem is that your installed version of cmake don't have the Visual Studio 8 2005 generator. You can simply check the available generator my typing the cmake command.

Following was the output for my system:
cmake version 2.6-patch 4
The following generators are available on this platform:
Unix Makefiles = Generates standard UNIX makefiles.
Eclipse CDT4 - Unix Makefiles
= Generates Eclipse CDT 4.0 project files.
KDevelop3 = Generates KDevelop 3 project files.
KDevelop3 - Unix Makefiles = Generates KDevelop 3 project files.

Now how to get the generator? Well i must say you have to dig this out your way. I found solution because i already knew with my trail and error that Visual Studio 8 2005 generator is available in cmake version 2.4. So i installed the cmake version 2.4 and then output of my cmake command shows that Visual Studio 8 2005 generator in the list.

cmake version 2.4-patch 8
The following generators are available on this platform:
Borland Makefiles = Generates Borland makefiles.
MSYS Makefiles = Generates MSYS makefiles.
MinGW Makefiles = Generates a make file for use with
mingw32-make.
NMake Makefiles = Generates NMake makefiles.
Unix Makefiles = Generates standard UNIX makefiles.
Visual Studio 6 = Generates Visual Studio 6 project files.
Visual Studio 7 = Generates Visual Studio .NET 2002 project
files.
Visual Studio 7 .NET 2003 = Generates Visual Studio .NET 2003 project
files.
Visual Studio 8 2005 = Generates Visual Studio .NET 2005 project
files.
Visual Studio 8 2005 Win64 = Generates Visual Studio .NET 2005 Win64
project files.
Visual Studio 9 2008 = Generates Visual Studio 9 2008 project files.
Visual Studio 9 2008 Win64 = Generates Visual Studio 9 2008 Win64 project
files.
Watcom WMake = Generates Watcom WMake makefiles.

Few important corrections:
In this blog post i suggested installing CMake version 2.4.8 for correcting "CMake Error: Could not create named generator Visual Studio 9 2008" error. It was a work around and because of lack of information.

Originally on my system, Cygwin was also installed. My Cygwin installation also contained CMake version 2.6 with limited generators. Now both Cygwin and CMake 2.6 were in the class path but Cygwin path was searched earlier then CMake 2.6 class path resulting in the use of Cygwin CMake instead of windows native installation of CMake 2.6.

This means the problem can easily be solved by ensuring that class paths are properly set so that windows native installation of CMake 2.6 is used.

This correction was informed to me by Bill Hoffman. Thanks Bill.

CMake 2.6 for windows show the following generators:

Generators

The following generators are available on this platform:
Borland Makefiles = Generates Borland makefiles.
MSYS Makefiles = Generates MSYS makefiles.
MinGW Makefiles = Generates a make file for use with
mingw32-make.
NMake Makefiles = Generates NMake makefiles.
Unix Makefiles = Generates standard UNIX makefiles.
Visual Studio 6 = Generates Visual Studio 6 project files.
Visual Studio 7 = Generates Visual Studio .NET 2002 project
files.
Visual Studio 7 .NET 2003 = Generates Visual Studio .NET 2003 project
files.
Visual Studio 8 2005 = Generates Visual Studio .NET 2005 project
files.
Visual Studio 8 2005 Win64 = Generates Visual Studio .NET 2005 Win64
project files.
Visual Studio 9 2008 = Generates Visual Studio 9 2008 project files.
Visual Studio 9 2008 Win64 = Generates Visual Studio 9 2008 Win64 project
files.
Watcom WMake = Generates Watcom WMake makefiles.
CodeBlocks - MinGW Makefiles= Generates CodeBlocks project files.
CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
Eclipse CDT4 - MinGW Makefiles
= Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - NMake Makefiles
= Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Unix Makefiles
= Generates Eclipse CDT 4.0 project files.

Thursday, August 20, 2009

Installing MySQL from Source on Windows

For my research project, i just started working on MySQL. One task was to build MySQL successfully using source code. Few things that took my time, i want to list them.

I was building the source using visual studio with build-vs8.bat file. The first error that i got was regarding vs8cache.txt file. The .bat file need this file but it is missing in the source. To solve this problem just make an empty vs8cache.txt file in the same folder where you have .bat file.

Second problem that i face was related to CMake. CMake issued me the error

CMake Error: Could not create named generator Visual Studio 9 2008

This error is because of the CMake version. On my system version 2.6.4 was installed. To solve this problem install the CMake version 2.4.8. This will solve this problem.

If you have different versions of visual studio installed on your system, then you might also need to edit the .bat file to change the line

cmake -G "Visual Studio 8 2005"

For example, visual studio 9 was intalled on my system but build-vs9.bat file was not working, might be because in source this .bat file is missing the usage of vs8cache.txt.

Any ways i was able to execute the .bat file successfully by changing cmake -G "Visual Studio 8 2005" to cmake -G "Visual Studio 9 2008".

Rest of the build process was wonderful for me.

Few important corrections:
In this blog post i suggested installing CMake version 2.4.8 for correcting "CMake Error: Could not create named generator Visual Studio 9 2008" error. It was a work around and because of lack of information.

Originally on my system, Cygwin was also installed. My Cygwin installation also contained CMake version 2.6 with limited generators. Now both Cygwin and CMake 2.6 were in the class path but Cygwin path was searched earlier then CMake 2.6 class path resulting in the use of Cygwin CMake instead of windows native installation of CMake 2.6.

This means the problem can easily be solved by ensuring that class paths are properly set so that windows native installation of CMake 2.6 is used.

This correction was informed to me by Bill Hoffman. Thanks Bill.