0

I was trying to understand how aligned malloc can be written referencing below post,

How to allocate aligned memory only using the standard library?

There are approaches which basically do this for 16 byte alignment, the memory which is returned is calculated using below,

((uintptr_t)mem+16-1) & ~ (uintptr_t)0x0F;

I am not getting that accepted answer is using 1024 byte memory allocation as it will be 16 byte aligned already. Is this understanding correct?

Shouldn't memory unaligned value be 1026 or 1029 byte which need to be made a multiple of 16 basically?

What about below example code,

#include <stdio.h>
#include <stdlib.h>

void myalignmalloc(size_t size, int align)
{
    size_t ext = size % align;
    size_t alignsize = size - ext + align; // memory divisible by align value
    printf("size: %ld alignsize: %ld\n", size, alignsize);
    // TODO: Add code use alignsize to allocate extra memory with alignment
}

//TODO: Add myfree function

int main(void)
{
    myalignmalloc(1031, 16);
    myalignmalloc(1031, 32);
    myalignmalloc(1061, 16);
    myalignmalloc(1061, 32);
    return 0;
}

//output
//size: 1031 alignsize: 1040
//size: 1031 alignsize: 1056
//size: 1061 alignsize: 1072
//size: 1061 alignsize: 1088

Is this not giving us correct memory size aligned by alignment by just making memory to be multiple of alignment?

mrigendra
  • 1,472
  • 3
  • 19
  • 33
  • Note that the correct `printf` conversion specifier for a `size_t` is `%zu`. Your `%ld` is wrong with respect to signedness, and might also be wrong with respect to width. – John Bollinger Mar 14 '23 at 22:07

1 Answers1

0

There are approaches which basically do this for 16 byte alignment, the memory which is returned is calculated using below,

((uintptr_t)mem+16-1) & ~ (uintptr_t)0x0F;

That's not computing the amount of memory, it's computing the aligned address.* The approach to which you link always allocates 15 bytes more than requested (for 16-byte alignment) to ensure that there are at least the requested number of bytes available starting at the earliest 16-byte-aligned address within the returned block.

I am not getting that accepted answer is using 1024 byte memory allocation as it will be 16 byte aligned already. Is this understanding correct?

It seems pretty clear to me that the accepted answer is making a 1039-byte (1024+15) allocation, not a 1024-byte allocation. And no, there is no guarantee that the pointer returned by malloc will be 16-byte aligned. The guarantee is that the memory will be aligned suitably for any object with a fundamental alignment requirement, which pretty much means the maximum alignment requirement that the implementation will choose by default for an object of any type. That need not be more than 1-byte alignment. It is more likely to be 4- or 8-byte alignment.

Shouldn't memory unaligned value be 1026 or 1029 byte which need to be made a multiple of 16 basically?

I have no idea what you mean.

What about below example code, [...]

Is this not giving us correct memory size aligned by alignment by just making memory to be multiple of alignment?

No. To ensure that an allocated block is big enough to contain at least size bytes starting at the first align-aligned address, without assuming alignment greater than 1 for the block itself, you must allocate size + (align - 1) bytes. That's not what the example code is computing.

Note also, by the way, that this approach has a more serious problem than the fact that the language spec does not guarantee it will work (since it probably will). The problem is that when it comes time to free the allocated memory, the free() function requires you to provide the pointer value returned by malloc(), not the aligned pointer derived from it if those differ. Therefore, you need somehow to retain that. The best option I can think of is to ensure to reserve a sufficient amount of additional space that you can store the "real" pointer in the allocated block, immediately before the aligned address.


*Or at least, it purports to do so. The C language in no way guarantees that that approach will work as advertized, but on many implementations, it will.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157