From: Ike Naar on 1 Mar 2010 04:36 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 1 Mar 2010 05:07 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 1 Mar 2010 05:42 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 1 Mar 2010 07:18 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 1 Mar 2010 07:21
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. |