From: Ike Naar on
In article <4b8b0f14$0$22380$426a74cc(a)news.free.fr>,
Nicolas George <nicolas$george(a)salle-s.org> wrote:
>Rainer Weikusat wrote in message <87r5o52day.fsf(a)fever.mssgmbh.com>:
>> This is not true. A storage area allocated by malloc is required to be
>> 'suitably aligned for any purpose' (for glibc, this means the pointer
>> value will be an integral multiple of eight). But this of course
>> doesn't 'magically' extend to the bytes which make up this area.
>
>No, but:
>
>- if pointer bar is aligned for any purpose, then it is in particular
> aligned for struct foo;
>
>- if pointer bar is aligned for struct foo, then taking the address of a
> member gives a pointer suitably for the type of that member;
>
>- if a pointer is suitably aligned for its type, then all arithmetic on that
> pointer, barring a cast to another type, stays thusly aligned.
>
>This implies that:
>
>struct foo *p = malloc(sizeof(struct foo) + 42 * sizeof(qux_t));
>qux_t q = &p->qux; /* assuming member qux has type qux_t */
>q[42] = SOME_QUX_VALUE;
>
>is always correct. With the caveat that, if qux is not the last element of
>the structure, the last access may have wrecked havoc in the following
>members, which must not be later accessed.

If qux is not the last element of the structure, but sizeof q[42]
is larger than the sum of the sizes of the following members, the
assignment to q[42] may still be overwriting memory beyond the end
of the malloced area.
From: Nicolas George on
Ike Naar wrote in message <hmg1qc$erf$1(a)news.eternal-september.org>:
>>struct foo *p = malloc(sizeof(struct foo) + 42 * sizeof(qux_t));
>>qux_t q = &p->qux; /* assuming member qux has type qux_t */
>>q[42] = SOME_QUX_VALUE;
> If qux is not the last element of the structure, but sizeof q[42]
> is larger than the sum of the sizes of the following members, the
> assignment to q[42] may still be overwriting memory beyond the end
> of the malloced area.

No, it will always be in the malloced area, because:

qux is a member of the structure, therefore we have:

offsetof(struct foo, qux) + sizeof(qux_t) <= sizeof(struct foo)

(char *)(&q[42]) = (char *)(q + 42)
(char *)q + 42 * sizeof(qux_t)
(char *)p + offsetof(struct foo, qux) + 42 * sizeof(qux_t)
<= (char *)p + sizeof(struct foo) + 41 * sizeof(qux_t)
<= (char *)p + argument_to_malloc - sizeof(qux_t)
From: Ike Naar on
In article <4b8b91da$0$9142$426a34cc(a)news.free.fr>,
Nicolas George <nicolas$george(a)salle-s.org> wrote:
>Ike Naar wrote in message <hmg1qc$erf$1(a)news.eternal-september.org>:
>> If qux is not the last element of the structure, but sizeof q[42]
>> is larger than the sum of the sizes of the following members, the
>> assignment to q[42] may still be overwriting memory beyond the end
>> of the malloced area.
>No, it will always be in the malloced area, because:
>qux is a member of the structure, therefore we have:
>[snip]

My mistake (I had forgot about qux already being a member of the struct).
Sorry for the confusion.
From: Rainer Weikusat on
Moi <root(a)invalid.address.org> writes:
> On Sun, 28 Feb 2010 23:41:41 +0100, Rainer Weikusat wrote:
>> Nicolas George <nicolas$george(a)salle-s.org> writes:
>>> Seebs wrote in message <slrnholl9c.s6g.usenet-nospam(a)guild.seebs.net>:
>>>> There exist compilers which will smack you down good if you access
>>>> more than one object in an array declared as containing one object.
>>>
>>> But the "array", here, is the one allocated by malloc. You can put
>>> anything you want anywhere in a memory area allocated by malloc.
>>
>> This is not true. A storage area allocated by malloc is required to be
>> 'suitably aligned for any purpose' (for glibc, this means the pointer
>> value will be an integral multiple of eight). But this of course doesn't
>> 'magically' extend to the bytes which make up this area. Eg, assuming
>> that p points to the start of the area, p + 1 is not 'suitably aligned
>> for any purpose' and this means that code like the example one below
>>
>> unsigned char *p;
>>
>> p = malloc(5);
>> *(unsigned *)(p + 1) = 0xabcdef;
>>
>> might either cause an alignment trap or some other non-desirable effect
>> (eg, on ARM9 with alignment traps disabled, the stored value will be
>> garbled). Even on x86, misaligned accesses incur a performance penalty
>> (which is an euphemism for 'alignment traps handled by hardware on die
>> due to general hopelessnes of this quest').
>
> You are trying to make this into an alignment issue.
> That was not the case. Please read the source.

I am not trying to make anything into anything else. The statement
'you can put anything you want anywhere in a memory area allocated by
malloc' is either wrong or at least very misleading.
From: Nicolas George on
Rainer Weikusat wrote in message <877hpwfd5i.fsf(a)fever.mssgmbh.com>:
> 'you can put anything you want anywhere in a memory area allocated by
> malloc' is either wrong or at least very misleading.

I accept "misleading": you can put anything you want, but access it only
according to valid (especially with regard to alignment) pointer arithmetic.
In this particular case, the arithmetic is good too.