Align a malloc ptr on a 64bit address

W

WebShaker

Hi.

I'd like to know if I can be sur that

uint64_t *buffer;
buffer = (uint64_t *)malloc(1024);

will return me a pointer 64 bit aligned.

Else if, how can I do that !!!

Thank's
Etienne
 
I

Ian Collins

Hi.

I'd like to know if I can be sur that

uint64_t *buffer;
buffer = (uint64_t *)malloc(1024);

will return me a pointer 64 bit aligned.

Consult the standard or your man pages. From my man page, which is
close to the standard's wording:

"The malloc() function returns a pointer to a block of at least size
bytes suitably aligned for any use."
Else if, how can I do that !!!

uint64_t* buffer = new uint64_t[1024/sizeof(uint64_t)];
 
J

Jens Thoms Toerring

WebShaker said:
I'd like to know if I can be sur that
uint64_t *buffer;
buffer = (uint64_t *)malloc(1024);
will return me a pointer 64 bit aligned.

I guess that you mean that the address is an integer mul-
tiple of 8 (there isn't a "bit-alignment" for memory).
And no, the address will only be an integer multiple of 8
if an object with that alignment requirement can exist on
the system under consideration (malloc() must return me-
mory properly aligned for any kind of object possible to
allocate memory for on the system).

So the good news is that in all common cases just calling
malloc() will do just fine with respect to alignment, even
if an uint64_t may not end up on at address divisible by 8
on systems that don't require an uint64_t to be aligned that
way.
Else if, how can I do that !!!

If this is a hard requirement (i.e. the guarantees of what
malloc() does aren't sufficient and you need alignment on a
8-byte boundary even if there are no objects that require
it) then you will have to allocate up to 8 extra bytes and
make sure that 'buffer' is aligned as you need it to be,
e.g. by using

char *tmp = (char *) malloc(1031);
uint64_t *buffer = (uint64_t *) ( tmp + 8 - tmp % 8 );

(With a bit of additional effort you can cut down the number
of extra bytes to allocate to 7, or, with more work, to the
bare minimum.)

Of course, the corresponding call of free() then has to be
made for 'tmp' and not 'buffer'. And if the number of bits
in a char isn't 8 things might be even more interesting;-)

Regards, Jens
 
E

Etienne

Le 07/12/2010 03:02, Jens Thoms Toerring a écrit :
char *tmp = (char *) malloc(1031);
uint64_t *buffer = (uint64_t *) ( tmp + 8 - tmp % 8 );

Ok thanks
I'll do that

char *tmp = (char *) malloc(1031);
uint64_t *buffer = (uint64_t *) ((tmp + 7) & 0xfffffff8);

Etienne
 
J

Jens Thoms Toerring

Etienne said:
Le 07/12/2010 03:02, Jens Thoms Toerring a écrit :

Oops, that should have been 1032 and not 1031!
I'll do that
char *tmp = (char *) malloc(1031);
uint64_t *buffer = (uint64_t *) ((tmp + 7) & 0xfffffff8);

You are aware that this only will work properly on a system
with 32-bit addresses? If you want to squeeze out that extra
byte then I would probably do

uint64_t *buffer = (uint64_t *) ( tmp % 8 ? ( tmp + 8 ) - tmp % 8 : tmp );

or something like this to get it also right for systems
with wider than 32-bit addresses.

Regards, Jens
 
E

Etienne

Le 07/12/2010 11:12, Jens Thoms Toerring a écrit :
You are aware that this only will work properly on a system
with 32-bit addresses? If you want to squeeze out that extra
byte then I would probably do

uint64_t *buffer = (uint64_t *) ( tmp % 8 ? ( tmp + 8 ) - tmp % 8 : tmp );

Yeap.
that's right.

Thank's
Etienne
 
C

Chris M. Thomasson

WebShaker said:
Hi.

I'd like to know if I can be sur that

uint64_t *buffer;
buffer = (uint64_t *)malloc(1024);

will return me a pointer 64 bit aligned.

Else if, how can I do that !!!

Perhaps something like this might be of use to you:

http://pastebin.com/xrjVnkQ2


You can use it like:
____________________________________________________________
#include <cstdio>
#include <align.hpp>


int main()
{
struct buffer_t
{
unsigned char buffer[8192];
};

unsigned char raw_buffer[align<buffer_t, 4096>::buf_size];
buffer_t* const aligned_buffer = align<buffer_t,
4096>::ptr_up(raw_buffer);

std::printf("raw_buffer == %p\n", (void*)raw_buffer);
std::printf("aligned_buffer == %p\n", (void*)aligned_buffer);

return 0;
}
____________________________________________________________


This basically aligned an `buffer_t' object on a 4096 byte boundary. Beware
that the main alignment calculation is non-portable to some "exotic"
architectures...
 
M

Miquel van Smoorenburg

I'd like to know if I can be sur that

uint64_t *buffer;
buffer = (uint64_t *)malloc(1024);

will return me a pointer 64 bit aligned.

In addition to all the answers you already got about malloc()
returning an address "suitable aligned", you can also use
posix_memalign() on any POSIX platform.

int posix_memalign(void **memptr, size_t alignment, size_t size);

The function posix_memalign() allocates size bytes and places the
address of the allocated memory in *memptr. The address of the alloâ€
cated memory will be a multiple of alignment, which must be a power of
two and a multiple of sizeof(void *).

Mike.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,143
Messages
2,570,822
Members
47,368
Latest member
michaelsmithh

Latest Threads

Top