views:

1344

answers:

4

Hi,

Most of experienced programmer knows data alignment is important for program's performance. I have seen some programmer wrote program that allocate bigger size of buffer than they need, and use the aligned pointer as begin. I am wondering should I do that in my program, I have no idea is there any guarantee of alignment of address returned by C++'s new operation. So I wrote a little program to test

for(size_t i = 0; i < 100; ++i) {
    char *p = new char[123];
    if(reinterpret_cast<size_t>(p) % 4) {
        cout << "*";
        system("pause");
    }
    cout << reinterpret_cast<void *>(p) << endl;
}
for(size_t i = 0; i < 100; ++i) {
    short *p = new short[123];
    if(reinterpret_cast<size_t>(p) % 4) {
        cout << "*";
        system("pause");
    }
    cout << reinterpret_cast<void *>(p) << endl;
}
for(size_t i = 0; i < 100; ++i) {
    float *p = new float[123];
    if(reinterpret_cast<size_t>(p) % 4) {
        cout << "*";
        system("pause");
    }
    cout << reinterpret_cast<void *>(p) << endl;
}
system("pause");

The compiler I am using is Visual C++ Express 2008. It seems that all addresses the new operation returned are aligned. But I am not sure. So my question is: are there any guarantee? If they do have guarantee, I don't have to align myself, if not, I have to.

Thanks.

Victor Lin.

+8  A: 

The alignment has the following guarantee from the standard (3.7.3.1/2):

The pointer returned shall be suitably aligned so that it can be converted to a pointer of any complete object type and then used to access the object or array in the storage allocated (until the storage is explicitly deallocated by a call to a corresponding deallocation function).

EDIT: Thanks to timday for highlighting a bug in gcc/glibc where the guarantee does not hold.

Richard Corden
In theory. In practice, if you're using gcc+glibc and SSE types on a 32-bit system, be aware of http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15795 .
timday
@timday: This problem with SSE types was also true of recent versions of MSVC++ (e.g. .NET 2003). Haven't tested on the latest version but I suspect it's still the case.
j_random_hacker
+2  A: 

The platform's new/new[] operator will return pointers with sufficient alignment so that it'll perform good with basic datatypes (double,float,etc.). At least any sensible C++ compiler+runtime should do that.

If you have special alignment requirements like for SSE, then it's probably a good idea use special aligned_malloc functions, or roll your own.

mfazekas
A: 

I worked on a system where they used the alignment to free up the odd bit for there own use!

They used the odd bit to implement a virtual memory system.

When a pointer had the odd bit set they used that to signify that it pointed (minus the odd bit) to the information to get the data from the database not the data itself.

I thought this a particulary nasty bit of coding which was far to clever for its own good!!

Tony

Tony Lambert
They're called tagged pointers, and they're not at all uncommon. Lots of programming language implementations use this trick to differentiate between a pointer and a integer.
geocar
And ARM interworking uses it - where applicable, ARM mode code addresses are even, thumb mode addresses are odd. I've seen an AVL tree implementation that used the bottom two bits to store the height difference of a node's subtrees. On limited systems, you stuff flag bits wherever you can :-)
Steve Jessop
+2  A: 

Incidentally the MS documentation mentions something about malloc/new returning addresses which are 16-byte aligned, but from experimentation this is not the case. I happened to need the 16-byte alignment for a project (to speed up memory copies with enhanced instruction set), in the end I resorted to writing my own allocator...

jheriko
I feel your pain...
j_random_hacker