After reading this, I have a similar question like this one, wondering how a memory allocator can work without violating the strict aliasing rules. But I am not wondering about re-using freed memory, I wonder about how allocated objects can be positioned within linear memory without violating strict aliasing.
All heap memory allocators I have looked at so far divide their memory in some sort of blocks, with a header in front. However, malloc returns a void *
and usually points to the memory right after the header. Here is an extremely narrowed down example to illustrate this.
#include <stddef.h>
struct block_header {
size_t size;
};
struct block_header *request_space(size_t size);
void *malloc(size_t size) {
struct block_header *block = request_space(size);
// I guess this violates strict aliasing, because the caller will
// convert the pointer to something other than struct block_header?
// Or why wouldn't it?
return block + 1;
}
I have been looking at this for a while now, but I see no way how an allocator could possibly position it's pointers in a memory region without violating strict aliasing. What am I missing?
According to the standard, these things never violate strict aliasing:
The thing you are not allowed to do in malloc'd space is read some memory as a different type than it was written as (except for the list of allowed aliasing types of course).
The text of the rule is in C11 6.5/7:
An object shall have its stored value accessed only by [...]
and the text in 6.5/6 explains that if we are in malloc'd space then the write imprints the type of the write onto the destination (and therefore there cannot be a type mismatch).
The code you've posted so far never does the forbidden thing so there is no apparent problem. There would only be a problem if someone used your allocator and then read the memory without writing it .
Footnote 1: 6.5/6 apparently is defective according to the committee response to DR236 but never fixed so who knows where that leaves us.
Footnote 2: as Eric points out the standard doesn't apply to implementation internals, but consider my comments in the context of some user-written allocator as in the other question you linked to.