3

In a previous question I asked related to bitwise operations I was told that a code that accesses to a char array with an int pointer (to operate on bigger chunks of bytes at a time) may be problematic if the char array is not aligned with a int address.

Then, thinking in C, I wondered what goes on when malloc allocates memory for an unknown type. For example, if I do void *p = malloc(sizeof(int));, do I get a valid char/int/long-aligned memory address?

According to some answers here in SO that cite the standard, "the pointer returned shall be suitably aligned so that it can be converted to a pointer of any complete object type".

Thus, I understand that I can go from char* to int* with no problems in this case:

char *p = malloc(16);
int *n = (int*)p; // use n a base of an array of 16 / sizeof(int) ints

Is it correct?

Moving to C++, it seems that the same rule appears in the standard. Then, can I assume that there are not alignment risks if I do this?

char *p = new char[16];
int *n = reinterpret_cast<int*>(p);
Community
  • 1
  • 1
ChronoTrigger
  • 8,459
  • 1
  • 36
  • 57
  • @JensGustedt I removed the comment, must have mis-read the code. I'm sure I thought there was a cast in the C code. Weird. – unwind Sep 09 '13 at 09:56
  • Yes, there was a cast, but I removed it after seeing your comment, @unwind. Sorry for not saying. – ChronoTrigger Sep 09 '13 at 10:05

3 Answers3

6

Yes, both malloc in C and C++ and new char[N] in C++ return a pointer that is maximally aligned. The alignment is that of the type max_align_t from or .

gcc-4.8 has a bug in this regard, fixed in gcc-4.9. Just include and use ::maxalign_t without the std:: prefix.

Support for over-aligned types, i.e. those whose alignment is greater than the above maximum, is implementation-defined. E.g. Posix offers posix_memalign to allocate memory with much greater alignments (e.g. page-aligned).

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • @user1095108: It's a whole can of worms how `` and `` interact with `std` and global namespaces - I think the net effect is that Nobody Knows For Sure and that you always have to have both... :-S – Kerrek SB Sep 09 '13 at 09:20
  • 1
    @KerrekSB - lest people get the wrong impression, `` will **always** put names into `std` and `` will **always** put names into the global namespace. It is indeed true that Nobody Knows For Sure what gets into the **other** namespace. – Pete Becker Sep 09 '13 at 13:54
1
char* p = new char[16];
int* n = reinterpret_cast<int*>(p);

This is fine, but even better is:

char* p = new char[16];
int* n = static_cast<int*>(static_cast<void*>(p));

Alternatively, you can use C++'s operator new, like this:

void* p = operator new(16);
int* n = static_cast<int*>(p);

Making for one less static_cast.

user1095108
  • 14,119
  • 9
  • 58
  • 116
  • Could you tell me the benefits from using two static casts? – ChronoTrigger Sep 09 '13 at 09:09
  • @ChronoTrigger `reinterpret_cast` will work on almost anything. But `static_cast` won't, it is safer and more portable to use. You don't need to use it in this case. – user1095108 Sep 09 '13 at 09:13
  • Note that C++11 explicitly makes `reinterpret_cast(p)` equivalent to `static_cast(static_cast(p))` in [expr.reinterpret.cast]/7. – avakar Sep 09 '13 at 10:01
  • 1
    @avakar but the argument of a `reinterpret_cast` could be anything, even a function pointer would be cast to `int*`, which is not possible with a `static_cast`. – user1095108 Sep 09 '13 at 10:08
0

malloc returns an address which is aligned correctly for any base type in C. That means it can be cast safely to pointers for all those types (int, long, double and so on).

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • It may be worth noting that the pointers are only required to have whatever alignment would be necessary to make them usable; if an architecture would have no problem reading a `long long` from an odd byte address, an implementation could legitimately return an odd byte address from `malloc`. – supercat May 10 '14 at 00:13