1

malloc doesn't allow arbitrary alignment. We can do this ourselfs, but we end up with a different pointer location. Free requires the original.

Is there any way to inform malloc of the new pointer so it can adjust itself and we won't have to store the old pointer/offset?

AbstractDissonance
  • 1
  • 2
  • 16
  • 31
  • You mean effectively telling `malloc` the alignment? – cadaniluk Jul 24 '16 at 18:03
  • If you change the pointer you were given, there is no way round remembering it or reverting to it, to `free` it. – Weather Vane Jul 24 '16 at 18:06
  • @Downvoter more or less. I can't use memaligned or anything like that. I can't calculate the original from the old. – AbstractDissonance Jul 24 '16 at 18:07
  • @WeatherVane Um, but if malloc could be informed, in some way, what the new pointer is, a sort of resize, then it can be done. This is not too hard except it relies on implementation details. It depends on if there is some way to inform malloc or not. So, there is a way around, if there is, which is why I'm asking. I'm not asking for absolutes unless you are saying there is nothing in the c library that can inform malloc of such behavior. – AbstractDissonance Jul 24 '16 at 18:09
  • See http://stackoverflow.com/questions/3839922/aligned-malloc-in-gcc maybe? – nebuch Jul 24 '16 at 18:09
  • @nebuch I do not have such functions in my version of C. – AbstractDissonance Jul 24 '16 at 18:10
  • If you can get `malloc()` to give you the right alignment in the first place (which might be possible, depending on the platform), that's better. But if you're overallocating and adding an offset to get the desired alignment, you could write the offset used right before the address you offset to so you can calculate the original address later -- but you'll need your own `malloc()` and `free()` wrappers to do that. – Dmitri Jul 24 '16 at 18:12
  • @Dmitri I have my wrappers. Yeah, I guess I could do that, the question is, though, how to tell the difference between an unaligned pointer and one that isn't? That is, if alignment = 0/1 and/or the original pointer = the aligned one. The algorithm would look right before to get the original address/offset. It would be impossible to know this case and I can't store the fact that alignment is 0 or 1. – AbstractDissonance Jul 24 '16 at 18:15
  • Depending on what you're doing this for, you may also be able to infer whether the pointer should be aligned by what you're using it for. Then you can overallocate enough for the needed offset, and just pass around the unadjusted pointer and calculate the actual start address of your data before use. – Dmitri Jul 24 '16 at 18:30
  • Might I ask: why do you need to do this? My suggestion is not to fight the language: just use what it gives you. – Bathsheba Jul 24 '16 at 18:56
  • @Dmitri: I can't predict the Alignment since it is user defined. It would all work great if it were possible to check if the pointer was aligned in the first place, which I believe it is not. (e.g., a malloced(ptr) == true type of test) – AbstractDissonance Jul 24 '16 at 18:58
  • @Bathsheba May I ask why you prefer to not speak at all? The whole point of anything is to push the boundaries. We are not cave men precisely because some cave man said that "This isn't good enough, it is flawed, I want better". My suggestion to you is to fight the language, make it better, stop accepting flaws and building on a faulty foundation. It is not the right way, regardless of what your hero said. – AbstractDissonance Jul 24 '16 at 19:00
  • What implementation are you targeting? Consider adding it as a tag. – a3f Jul 24 '16 at 19:47

2 Answers2

2

C11 introduces aligned_alloc which supports specifying an alignment. It's implementation defined which alignments are supported, but on POSIX it should be like posix_memalign(3), which supports any power of two that's a multiple of sizeof(void*).

Also consider, if regular malloc suffices. malloc has an alignment of _Alignof(max_align_t) for all allocations.

In case, C11 isn't available there is posix_memalign(3). In case you are on Windows, there is a _aligned_alloc starting with MSVC 2015 or use VirtualAlloc and allocate a page-aligned buffer.

If neither of these works, you will have to roll an own solution on top of malloc. Get the next aligned address, save the alignment on the two preceding bytes. When calling your free wrapper, get the 2 preceding bytes, subtract them from the pointer and free the result.

a3f
  • 8,517
  • 1
  • 41
  • 46
1

Well, I believe in C11 there is such a beast

Defined in header <stdlib.h>

void *aligned_alloc( size_t alignment, size_t size );
Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64