How to define alignment for structure member variables

25 01 2018


Every data type has an alignment associated with it which is mandated by the processor architecture rather than the language itself. Aligning data elements allows the processor to fetch data from memory in an efficient manner and thereby improves performance. The compiler tries to maintain these alignments for data elements to provide optimal performance. How can we change it?

Windows provide pack directive to set the alignment for structure, union, and class members.
1. #pragma pack(n) – Sets the new alignment.
2. #pragma pack(push)- Pushes the current alignment setting on an internal stack
3. #pragma pack(pop)- Restores the alignment setting to the one saved at the top of the internal stack

struct Struct1
{
  char a;
  int b;
  char c;
};

//pushes the current alignment setting on an internal stack
#pragma pack(push) 
#pragma pack(1) //sets the alignment 
struct Struct2
{
  char a;
  int b;
  char c;
};
#pragma pack(pop) //restores the alignment

struct Struct3
{
  char a;
  int b;
  char c;
};

#pragma pack(push) //pushes the current alignment 
#pragma pack(2) //sets the alignment 
struct Struct4
{
  char a;
  int b;
  char c;
};
#pragma pack(pop) //restores the alignment

int _tmain(int argc, _TCHAR* argv[])
{
  /*| 1 | 2 | 3 | 4 |

    | a(1) | pad.................. |
    | b(1) | b(2) | b(3) | b(4)    |
    | c(1) | pad.................. | */
  int nSizeWithDefaultPadding = sizeof(Struct1); //12

  /*| 1 |

    | a(1) |
    | b(1) | 
    | b(2) | 
    | b(3) | 
    | b(4) |
    | c(1) |  */
  int nSizeWithPadding1 = sizeof(Struct2);//6
  int nSizeAfterRestored = sizeof(Struct3 );//12

  /*| 1  | 2 |

  | a(1) | pad  |
  | b(1) | b(2) |  
  | b(3) | b(4) |
  | c(1) | pad  |  */
  int nSizeWithPadding2 = sizeof(Struct4);//8
	return 0;
}


In Visual Studio 2015 and later we can use the standard alignas and alignof operators for same.





How to debug a function in release mode

29 07 2015


The Visual Studio IDE provides different optimization options that help us to create code for maximum speed or minimum size. Mostly we select /O1 optimizes code for minimum size when we build our project in release configuration. But you might be observed that the variable values may not be displayed correctly in the watch window if we try to debug our source code in release configuration. Of-course, we have options to enable debugging support in release mode. But just think in case if you want to debug just one function in release mode!!!

Pragma directives specify machine- or operating-specific compiler features. The compiler optimization can be performed on a function-by-function basis using #prgma optimize statement.

#pragma optimize( "[optimization-list]", {on | off} )

We can disable the optimization using the optimize pragma with the empty string (“”).

#pragma optimize( "", off )
void FunctionToDebug()
{
}
#pragma optimize( "", on ) 


Some pragmas provide the same functionality as compiler options. When a pragma is encountered in source code, it overrides the behavior specified by the compiler option.





How to check whether a memory address is valid

29 07 2015


As a programmer, some time we may need to check whether the specified memory block is within our application’s memory space. How can we do it?

Windows provides an API AfxIsValidAddress for same.

BOOL AfxIsValidAddress(const void* lp, UINT nBytes, BOOL bReadWrite = TRUE);

Parameters
lp : Points to the memory address to be tested.
nBytes : Contains the number of bytes of memory to be tested.
bReadWrite : Specifies whether the memory is both for reading and writing (TRUE) or just reading (FALSE).

Return Value
AfxIsValidAddress() returns TRUE if the passed parameter points to at least nBytes of accessible memory. If bReadWrite is TRUE, the memory must be writable; if bReadWrite is FALSE, the memory may be const.





How to enable Memory Leak Detection

7 03 2014

Memory leak is defined as the failure to correctly deallocate the memory that was previously allocated and it is a hard to detect bug in C++ applications. The program that leaks large amount of memory or leak progressively may decrease the performance of your system. These kinds of memory leaks make unexpected crashes in our applications and the most difficult part is to reproduce the defect and find out the root cause of same. So it is always better to analyze the memory leaks together with the functionality testing of our application. Lots of 3rd party tools are available for detecting memory leaks in our C++ code. AQTime is one of the best tools I ever used.But in this post I would like to discuss about enabling memory leak detection using Windows APIs.

The visual studio debugger along with C Run-Time Libraries (CRT) can help us to detect memory leaks in our code.

To enable the debug heap functions, include the following statements in your program:

#define _CRTDBG_MAP_ALLOC
#include "stdlib.h"
#include "crtdbg.h"

you can place a call to _CrtDumpMemoryLeaks before an application exit point to display a memory-leak report when your application exits:

_CrtDumpMemoryLeaks();

This displays memory leak information in the Output window of Visual Studio IDE.

The #include statements must be in the order shown above. Otherwise, the functions you use may not work correctly.





How to find all files from a folder

29 10 2013

Sometimes we may need to find out all files belongs to a folder. How we will do it?


The FindFirstFile function opens a search handle and returns information about the first file with a name that matches the specified pattern. After the search handle is established, use the FindNextFile function to search for other files that match the same pattern.

void FindFilesFromFolder(CString p_strFolderPath, CStringArray* p_pFiles)
{
    HANDLE hFile = INVALID_HANDLE_VALUE;
    WIN32_FIND_DATA   FindFileData;
    CString strTemp;

    strTemp.Format(_T("%s\\%s"), p_strFolderPath, _T("\\*.*"));
    hFile = FindFirstFile(strTemp, &FindFileData);
    CString strFilePath;

    if (INVALID_HANDLE_VALUE != hFile) 
    {
        do
        {
            //Skip directories
            if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes)
                continue;

            strFilePath.Format(_T("%s\\%s"), p_strFolderPath, FindFileData.cFileName);
            p_pFiles->Add(strFilePath);
            strFilePath.Empty();            
        } while(FindNextFile(hFile, &FindFileData));

        FindClose(hFile);
    }    
}


Please give the exact file extension incase if you need to find out only files which has specific extension.





How to zip/unzip files

28 10 2013

If we search ‘How to zip/unzip files’ in any search engines, we will get lots of links to Open Source Softwares(OSS) to do it. But once you use OSS in your application, then definitely you should have to take care of OSS clearnce before you make Product release to the market. So how we can do it our own without any dependecy with OSS components?

Windows Shell library do it for free of cost.

Step 1 : Create an empty zip file

Step 2 : Add files to it using shell32 CopyHere method.


ZIP File

void CreateEmptyZipFile(CString strPath)
{
	BYTE startBuffer[] = {80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
	FILE *f = _wfopen(strPath.GetBuffer(strPath.GetLength()), _T("wb"));
	strPath.ReleaseBuffer();
	fwrite(startBuffer,sizeof(startBuffer),1,f);
	fclose(f); 
}

void ZipFile(CString strSrc, CString strDest)
{
	//Create an empty zip file
	CreateEmptyZipFile(strDest);

	BSTR bstrSource = strSrc.AllocSysString();
	BSTR bstrDest = strDest.AllocSysString();

	HRESULT hResult = S_FALSE;
	IShellDispatch *pIShellDispatch = NULL;
	Folder *pToFolder = NULL;		
	VARIANT variantDir, variantFile, variantOpt;

	CoInitialize(NULL);

	hResult = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, 
		IID_IShellDispatch, (void **)&pIShellDispatch);

	if (SUCCEEDED(hResult))
	{
		VariantInit(&variantDir);
		variantDir.vt = VT_BSTR;
		variantDir.bstrVal = bstrDest;
		hResult = pIShellDispatch->NameSpace(variantDir, &pToFolder);

		if (SUCCEEDED(hResult))
		{
			VariantInit(&variantFile);
			variantFile.vt = VT_BSTR;
			variantFile.bstrVal = bstrSource;

			VariantInit(&variantOpt);
			variantOpt.vt = VT_I4;
			variantOpt.lVal = FOF_NO_UI;

			hResult = pToFolder->CopyHere(variantFile, variantOpt);
			Sleep(1000);
			pToFolder->Release();
		}

		pIShellDispatch->Release();
	}

	CoUninitialize();
}

UNZIP File

void UnZipFile(CString strSrc, CString strDest)
{
	BSTR source = strSrc.AllocSysString();
	BSTR dest = strDest.AllocSysString();

	HRESULT hResult = S_FALSE;
	IShellDispatch *pIShellDispatch = NULL;
	Folder *pToFolder = NULL;		
	VARIANT variantDir, variantFile, variantOpt;

	CoInitialize(NULL);

	hResult = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, 
		IID_IShellDispatch, (void **)&pIShellDispatch);
	if (SUCCEEDED(hResult))
	{
		VariantInit(&variantDir);
		variantDir.vt = VT_BSTR;
		variantDir.bstrVal = dest;
		hResult = pIShellDispatch->NameSpace(variantDir, &pToFolder);

		if  (SUCCEEDED(hResult))
		{
			Folder *pFromFolder = NULL;
			VariantInit(&variantFile);
            variantFile.vt = VT_BSTR;
            variantFile.bstrVal = source;
			pIShellDispatch->NameSpace(variantFile, &pFromFolder);

			FolderItems *fi = NULL;
			pFromFolder->Items(&fi);

			VariantInit(&variantOpt);
            variantOpt.vt = VT_I4;
            variantOpt.lVal = FOF_NO_UI;			

			VARIANT newV;
			VariantInit(&newV);
			newV.vt = VT_DISPATCH;
			newV.pdispVal = fi;
			hResult = pToFolder->CopyHere(newV, variantOpt);
			Sleep(1000);
			pFromFolder->Release();
            pToFolder->Release();
		}
		pIShellDispatch->Release();
	}

	CoUninitialize();
}


It has been used a Folder object also in the program. Please refer MSDN for more information. Please don’t forget to include shell32.lib and Shellapi.h to your project.





dynamic_cast throws unhandled exception in VC++ 6.0

17 05 2013


Usually we upgrade our projects to higher versions of Visual Studio IDE for getting latest Windows libraries and making our project to be compatible with latest technologies. But recently we had to downgrade one of our DLLs to VC++ 6.0 from VS2005. As first step, we created new project in VC++ 6.0, resolved all compiler errors and successfully compiled it in VC++ 6.0 IDE. But when we integrated it with client application, it started throwing unhandled exception from wherever it used dynamic_cast. 😦


We have to explicitly enable Run-Time Type Information(RTTI) for our project in VC++ 6.0 compiler. In Visual C++ 2005, RTTI is on by default.

Enabling RTTI in VC++ 6.0 Project,

1) Open the project’s Property Page

2) Click the C/C++ Tab

3) Select C++ Language Category

4) Select Enable Run-Time Type Information (RTTI) checkbox

RTTI


typeid operator also fail if we don’t enable RTTI in our project.





How to read INI files

8 05 2013

INI files(.INI) are simple text files with a basic structure composed of sections and properties and which is used for some configuration settings. Till Microsoft introduced registry, the INI file served as the primary mechanism to configure operating system features. Even if it is obsolete, developers may still need to use it.

Windows provides APIs for reading and writing settings from classic Windows .ini files. The following APIs are available for reading data from INI files.
GetPrivateProfileInt
GetPrivateProfileSection
GetPrivateProfileSectionNames
GetPrivateProfileString
GetPrivateProfileStruct
GetProfileInt
GetProfileSection
GetProfileString

INIReader.h

class CINIReader
{

public:
CINIReader()
{
    m_pSectionList = new CStringList();
    m_pSectionDataList = new CStringList();
}

~CINIReader()
{
    delete m_pSectionList;
    delete m_pSectionDataList;
}

    void SetInfFileName(CString p_strInfFileName);
    BOOL IsValidSection(CString p_strSectionName);
    CStringList* GetSectionNames()
    CStringList* GetSectionData(CString p_lpSectionName);

private:
    CString m_strInfFileName;
    CStringList* m_pSectionList;
    CStringList* m_pSectionDataList;	    
};

INIReader.cpp

void CINIReader::SetInfFileName(CString p_strInfFileName)
{
m_strInfFileName = p_strInfFileName;
}

BOOL CINIReader::IsValidSection(CString p_strSectionName)
{
BOOL bReturnValue = FALSE;

if (!m_strInfFileName.IsEmpty())
{
TCHAR lpszReturnBuffer[nBufferSize];

DWORD dwNoOfCharsCopied = GetPrivateProfileString(p_strSectionName, NULL,
_T(""), lpszReturnBuffer, nBufferSize, m_strInfFileName);

bReturnValue = (dwNoOfCharsCopied > 0) ? TRUE : FALSE;
}

return bReturnValue;
}

CStringList* CINIReader::GetSectionNames()
{
if (m_pSectionList)
{
m_pSectionList->RemoveAll();
TCHAR lpszReturnBuffer[nBufferSize];
GetPrivateProfileSectionNames(lpszReturnBuffer, nBufferSize, m_strInfFileName);
TCHAR* pNextSection = NULL;
pNextSection = lpszReturnBuffer;
m_pSectionList->InsertAfter(m_pSectionList->GetTailPosition(), pNextSection);
while (*pNextSection != 0x00)
{
pNextSection = pNextSection + strlen(pNextSection) + 1;
if(*pNextSection != 0x00)
{
m_pSectionList->InsertAfter(m_pSectionList->GetTailPosition(), pNextSection);
}
}
}

return m_pSectionList;
}

CStringList* CINIReader::GetSectionData(CString p_lpSectionName)
{
if (m_pSectionDataList)
{
m_pSectionDataList->RemoveAll();
TCHAR lpszReturnBuffer[nBufferSize];
GetPrivateProfileSection(p_lpSectionName, lpszReturnBuffer, nBufferSize, m_strInfFileName);
TCHAR* pNextSection = NULL;
pNextSection = lpszReturnBuffer;
m_pSectionDataList->InsertAfter(m_pSectionDataList->GetTailPosition(), pNextSection);
while (*pNextSection != 0x00)
{
pNextSection = pNextSection + strlen(pNextSection) + 1;
if(*pNextSection != 0x00)
{
m_pSectionDataList->InsertAfter(m_pSectionDataList->GetTailPosition(), pNextSection);
}
}
}

return m_pSectionDataList;
}

We can discuss about INI writer in our next post.





How to register a vectored exception handler

2 05 2013

Recently just after we deployed our project in a Client machine, they reported a sporadic crash issue in their machine. :(. After analyzing the dump file, our Architect team found out that its happening from a particular COM Component. Unfortunately I was responsible for that component. 😦 😦

I tried to reproduce same issue in my development machine and was able to reproduce only in release configuratiin mode. Actually I have only the source code of my component in my machine.
So I was thinking about, how to find out this crash location in my source code. Yes, you are right some loggin mechanism. 🙂 Plus some exception handling mechanism too. 🙂 🙂

In case of exception occouered in our code, the operating system try to find out a handler which tells how to proceed now. If it fails, then we will get error message that our application is going to close!!!
In order to find such exception handler, the system has a fixed order to search.
It will start with the vectored exception handlers. So we can set a Vectored exception handler for our application using Windows API AddVectoredExceptionHandler.It registers a vectored exception handler.
The parameter of exception handler is pointer to a structure EXCEPTION_POINTERS. From this structure we get exception code and address where the exception occurred. Then using the method SymGetSymFromAddr64 from Dbghelp.dll, we can locate the symbol(function name) for that address.

char *Symbol(DWORD dwAddr)
{
    typedef struct _IMAGEHLP_SYMBOL64_L {
        DWORD   SizeOfStruct;
        DWORD64 Address;
        DWORD   Size;
        DWORD   Flags;
        DWORD   MaxNameLength;
        CHAR    Name[1];
    } IMAGEHLP_SYMBOL64_L, *PIMAGEHLP_SYMBOL64_L;

    typedef BOOL (__stdcall *pfnSymInitialize) (HANDLE hProcess,
        PCSTR UserSearchPath, BOOL fInvadeProcess);
    typedef BOOL (__stdcall *pfnSymGetSymFromAddr64) (HANDLE hProcess,
        DWORD64 qwAddr, PDWORD64 pdwDisplacement, PIMAGEHLP_SYMBOL64_L  Symbol);

    static BOOL	bSymLoad;
    static char symName[1024];
    static IMAGEHLP_SYMBOL64_L *pSym = NULL;
    static pfnSymInitialize SymInit;
    static pfnSymGetSymFromAddr64 SymName;

    if (!bSymLoad)
    {
        HMODULE hMod;			
        if ( (hMod = LoadLibrary(__T("Dbghelp.dll"))) &&
            (SymInit = (pfnSymInitialize) GetProcAddress(hMod, "SymInitialize")) &&
            (SymName = (pfnSymGetSymFromAddr64) GetProcAddress(hMod, "SymGetSymFromAddr64")))
        {
            bSymLoad = SymInit(GetCurrentProcess(), NULL, true);
            pSym = (IMAGEHLP_SYMBOL64_L *) malloc(sizeof(IMAGEHLP_SYMBOL64_L) + 2000);
        }
    }

    if (bSymLoad)
    {
        DWORD64  dwDisplacement = 0;
        pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64_L);
        pSym->MaxNameLength = 2000;

        if (SymName(GetCurrentProcess(), dwAddr, &dwDisplacement, pSym))
        {
            return &pSym->Name[0];
        }
    }

    return NULL;
}

LONG CALLBACK VectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
    CString strMsg;
    strMsg.Format("Exception code: 0x%x (%s)", ExceptionInfo->ExceptionRecord->ExceptionCode,
		Symbol((DWORD) ExceptionInfo->ExceptionRecord->ExceptionAddress) );
	return EXCEPTION_CONTINUE_SEARCH;
}

BOOL InitInstance()
{
    AddVectoredExceptionHandler(1, VectoredExceptionHandler);
}


It uses few symbol handler functions from Dbghelp.dll, which gives applications easy and portable access to the symbolic debugging information of an executable image.





How to pass variable number of arguments to a function

30 04 2013

How to write functions which takes variable number of arguments in our program.

In C++, we can write functions with three dots(…) as parameter. This will make that function to support variable number of arguments. The va_arg, va_end, and va_start macros provide access to function arguments when the number of arguments is variable.

void LogError(TCHAR * format, ...)
{
   va_list args;
   int len;
   TCHAR *buffer;

   va_start(args, format);
   len = _vscprintf(format, args) + 1;
   buffer = (TCHAR *) _alloca( len * sizeof(TCHAR) );
   vsprintf_s( buffer, len, format, args );
   CString strErrMsg = buffer;
}

int Sum(int noOfArgs, ...)
{
    int nSum = 0;
    va_list args;
    va_start(args, noOfArgs);
    nSum = va_arg(args, int);
    for(int i = 2; i <= noOfArgs; i++) 
    {
        nSum += va_arg(args, int);
    }
    va_end(args);
    return nSum;
}

void main()
{
    int nSum = Sum(5, 1, 2, 3, 4, 5);
    LogError(_T("Failed - %s, ErrorCode - %d"), "AccessDenied", 111);
}


These macros are defined in STDARG.H file.