C++: Empty a vector for real

clear() is the method used to empty a STL vector in C++. However, it merely sets the size of the vector to zero. In almost all STL implementations, the vector is still consuming the same amount of memory it was before the call to clear(). This can be seen by calling the capacity() method, which returns the actual number of items which the vector can hold without needing or reallocating any new memory.

#include <iostream>
#include <vector>
int main()
{
    vector< int > v( 1000000 );
    v.clear();
    std::cout << v.capacity() << std::endl; // 1000000
    return 0;
}

But, there will be situations where memory is tight and you would like to actually clear a vector of all its memory. This can be achieved using the shrink_to_fit() method, which was introduced in C++11:

v.clear();
v.shrink_to_fit(); // Capacity of v is now 0

If you are using an old C++ compiler or STL implementation that does not support shrink_to_fit(), there is another trick to empty a vector: swap its contents with a vector that is actually empty:

vector< int >().swap( v ); // Capacity of v is now 0

Our original vector now points to the (empty) space of the new vector. The new vector now points to the capacity of the old vector. But, the lifetime of the new vector is the scope of this statement. As soon as that scope ends, the new vector is deleted, thus freeing the memory occupied by the old vector.

Tried with: Visual C++ 2010

C++: abs() and its quirk with INT_MIN

If you use the abs() function from cmath, then you need to be aware of one little quirk. The abs() function returns the absolute value of the signed integer passed as input. It is declared as:

int abs( int );

abs() works as defined for all input integers, except for one integer: the INT_MIN. For 32-bit integers, the value of INT_MIN is -2147483648. abs( INT_MIN ) returns INT_MIN back!

To see why, consider the binary representation of any signed integral type (char, short, int and long). The range of the positive integer values that can be represented is one less than that of negative integer values.

For 32-bit integers, the largest representable integer (INT_MAX) is 2147483647, whereas the smallest representable integer (INT_MIN) is not -2147483647, but it is -2147483648. Though the number of values that can be represented by an integral type is even, integer value 0 steals one space and thus the positive integer values lose one space in their range.

Coming back to abs(), since its return type is the same as the input type it simply cannot represent the positive value (-INT_MIN) in an int. Thus, it returns back INT_MIN.

The binary representation of 0 is 00000000000000000000000000000000 and the binary representation of INT_MIN is 10000000000000000000000000000000. That is, INT_MIN is same as 0, with MSB set to 1. Quirks of integers, such as with abs(), could have been avoided if the int format had been defined with two zero values: a positive zero (00000000000000000000000000000000) and a negative zero (10000000000000000000000000000000).

Anyway, the reason you need to be careful about abs() is because you might be using its return value to index into an array. Indexing an array using a negative value can be disastrous or result in a hard-to-replicate bug.

C++: Static Class Definition

In C++, the static specifier is only meaningful when applied on functions and variables. But surprisingly, C++ allows static to be used on a class definition:

static class Car
{
    int _speed;
};

This specifier is useless on the class definition since it does not mean anything! This compiles successfully with with Visual C++, only generating a C4091 warning:

warning C4091: 'static ' : ignored on left of 'Car' when no variable is declared

This hints at the reason why C++ allows static on a class definition. It is to support the definition of a class and the creation of a static object of that class in a single statement:

static class Car { int _speed } fooCar;

The above is equivalent to:

class Car
{
    int _speed;
};

static Car fooCar;

C++: Mantissa and Exponent of Floating Point Number

The little-known frexp function from the C/C++ standard library can be used to extract the mantissa and exponent of a floating point number (float, double or long double):

#include <cmath>

const double d = 0.123;
int exponent;
const double mantissa = frexp( d, &exponent );

// Double:   0.123
// Mantissa: 0.984
// Exponent: -3

A few notes:

  • frexp assumes that a floating point number is represented as mantissa * 2 ^ exponent. This is a simple and convenient representation to work with. But, do keep in mind that this is not how the floating point number is actually stored.
  • For a positive floating point number, the mantissa returned by frexp always lies in the range [0.5, 1.0). This range is enough since a mantissa in the range (0.0, 0.5) can be converted to a value in [0.5, 1.0) by multiplying it by a suitable 2 ^ exponent. Note that the exponent can be negative or positive. The exception to this mantissa value is the floating point number 0.0, which is displayed as it is.
  • The mantissa and exponent returned by frexp are in no way related to the actual mantissa and exponent values stored in the floating point number format. For example, the IEEE-754 format uses a sign bit and modifies the exponent value using an exponent bias.

Output 3D Mesh to PLY File

The PLY file format is one of the simplest ways to read and write a 3D mesh. There are a few libraries which can be used to read or write PLY files from your code.

However, if you are dealing with a simple triangulated 3D mesh, there is no need to use a library. Writing such a mesh out to a PLY file from your code is very simple. Here is sample code in C++:

C++: Print Current Date and Time

The easiest way to obtain the date and time string in C++ is to use time, localtime_s and asctime_s. The output string is of the form Tue Aug 02 15:11:23 2011.

Here is the self-explanatory code:

#include <ctime>

time_t curTime;
struct tm locTime;
const int TimeStrLen = 26;
char timeStr[ TimeStrLen ];

if (    ( -1 != time( &curTime ) )                          // Seconds since 01-01-1970
    &&  ( 0 == localtime_s( &locTime, &curTime ) )          // Convert to local time
    &&  ( 0 == asctime_s( timeStr, TimeStrLen, &locTime ) ) // Convert to string
    )
{
    cout << "Date-time is: " << timeStr;
}
else
{
    cerr << "Error calculating date-time!" << endl;
    exit( 1 );
}

C++: A Simple Singleton

The simplest Singleton possible in C++, illustrated with a Configuration object that is used to read/write the application configuration:

class _Config
{
public:
    int _fileNum;
    int _charNum;
};

// Singleton
_Config& Config()
{
    static _Config _config;
    return _config;
}

int main()
{
    Config()._fileNum = 1024;
    Config()._charNum = 256;
    return 0;
}

Not only is this simple, it also avoids the initialization problems associated with a global static object.

C++: pragma once

With both Visual C++ and GCC supporting pragma once completely, I do not see any reason to still use the include guards. Include guards were always a messy solution and I am glad that their death certificate has been written. For example, I would typically use a ALL_CAPS version of the header filename as the defined name. But then, one had to remember to change this whenever the file was renamed. Also, an include guard involved two pieces of code (the #ifndef-#define and the #endif) between which the header code was placed, again too messy and problematic.

In comparison, using #pragma once is straightforward. As a bonus, the horrendous C++ compilation time might be reduced a bit due to optimizations for pragma once by both these compilers.

C++: High-Resolution Timer

Timers are useful to find the performance bottlenecks in code. If a timer resolution of 1ms is enough for your application, you can use the clock function from <ctime> as shown here.

However, if you need timers of a far higher resolution on Windows, a popular choice is to use the high-resolution performance counter API. All calls of this API rely on a LARGE_INTEGER data type.

Use QueryPerformanceCounter to note down the begin and end times of your code:

#include <windows.h>

LARGE_INTEGER beginTime;
QueryPerformanceCounter( &beginTime );

// Code to measure ...

LARGE_INTEGER endTime;
QueryPerformanceCounter( &endTime );

Use QueryPerformanceFrequency to find the timer frequency. Use that to convert the time difference to seconds:

LARGE_INTEGER timerFreq;
QueryPerformanceFrequency( &timerFreq );
const double freq = 1.0f / timerFreq.QuadPart;

const double timeSeconds = ( endTime.QuadPart - beginTime.QuadPart ) * freq;

A PerfTimer class that exposes this as simple start(), stop() and value() calls is available here.

Tried with: Visual C++ 2008

CUDA: C++ Wrapper for cudaMalloc

A typical usage of cudaMalloc to allocate memory on the device is:

const int arraySize = 100;
Foo* fooArray       = NULL;

const int arraySpace = arraySize * sizeof( *fooArray );
cudaMalloc( &fooArray, arraySpace );

cudaMalloc is a C function and its usage in C++ is quite messy for 2 reasons. First, fooArray cannot be defined and assigned the allocated memory in the same statement. Second, a calculation of the array size in bytes is required.

A simple C++ wrapper for cudaMalloc using a template function can handle both of these problems:

template< typename T >
T* myCudaMalloc( int size )
{
    T* loc          = NULL;
    const int space = size * sizeof( T );
    cudaMalloc( &loc, space );
    return loc;
}

const int arraySize = 100;
Foo* fooArray       = myCudaMalloc< Foo >( arraySize );

I wish the function could deduce the type without requiring its to be explicitly specified, as myCudaMalloc< Foo >. But, that would mean deducing the type based solely on the function return type, which is not possible in C++.

Tried with: CUDA 3.2