On 07/27/2018 08:21 UTC, Florian Weimer wrote:
On 07/27/2018 05:10 AM, John Reiser wrote:
Always requiring 16-byte alignment on x86_64 can waste too much space
due to internal fragmentation. The rule should be:
The required alignment is at least min(16, max_p2_divisor_of_size)
where the second argument max_p2_divisor_of_size is the maximum power of 2
that divides the requested size [when 0!= size].
Thus a request for 6 bytes may be satisfied by a block whose address is
divisible by 2.
But this rule is wrong. Consider this:
struct string
{
size_t length;
char data[];
};
To allocate a one-byte string, malloc would be called with an argument of sizeof (size_t) + 1. Your rule gives alignment 1, but in reality, alignment 4 or 8 is required.
(Flexible struct members are not strictly required to implement this, of course, so it's not a new problem at all.)
As written, sizeof(struct string) is 4 on a 32-bit machine, or 8 on a 64-bit machine.
Actually storing something in data[] requires more bytes; the question is,
"How many more?". The answer is round_up(size_for_data, sizeof(string.length))
in order to guarantee alignment for string.length; and this calculation
should be done by the caller of malloc(), not inside malloc().
The key principle is that sizeof(foo) must be the stride of an array of foo,
and the array must guarantee alignment of each element in the array.
For illustration: if data[] is to store 5 bytes, then that is equivalent to
struct string5
{
size_t length;
char data[5];
};
and sizeof(struct string5) is 12 on a 32-bit machine, or 16 ln a 64-bit machine.
So 12, or 16, should be the argument to malloc().
_______________________________________________
devel mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxx
Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedoraproject.org/archives/list/devel@xxxxxxxxxxxxxxxxxxxxxxx/message/5OZHNIM2Y4S2R65LND6Z46CFQATJM2FU/