2

The dsPic30/33 and 18E/F parts will produce memory faults if 16-bit accesses are made to memory on odd addresses. When allocating heap memory using malloc(), is the return address guaranteed to be word-aligned? (i.e. even)

malloc, you will recall, takes an argument in bytes, not words.

The documentation I've been able to find (16-bit Language Tools Library Reference Manual 50001456J.pdf) is mute on this issue.

==== Edit: I should add that I've only ever received even (word-aligned) addresses from malloc(), so everything's been working well so far. Nevertheless, my code will cause a trap if I ever get an odd address (because I do perform things like ((uint16_t *)foo)[3] = 20000;). Therefore, I want to be sure that even address are always returned by malloc().

EBlake
  • 735
  • 7
  • 14
  • Does the language have any type that performs 16-bit accesses? Anything like `some_type foo; foo = 3;` where the `=` does a 16-bit access? If so, `malloc` *must* work. – David Schwartz Aug 17 '16 at 22:34
  • @DavidSchwartz well it's possible that the implementation is bugged – M.M Aug 17 '16 at 22:35
  • The documentation wouldn't help you if it's a bug. Bugs are typically undocumented. If it has a real 16-bit type, then `malloc` has to give a legal pointer to one. – David Schwartz Aug 17 '16 at 22:35
  • @DavidSchwartz These microcontrollers are natively 16-bit (operands and memory access), but they can also operate (and address) individual bytes. Words must be on even addresses, whereas bytes can be accessed on any address. – EBlake Aug 17 '16 at 22:55

3 Answers3

2

The C Standard mandates that malloc() must return a pointer satisfying any memory alignment requirement imposed by the implementation for any object that could fit within the allocation. If a compiler were to process all memory accesses in a way that would work regardless of alignment, the malloc() implementation could return pointers with arbitrary alignment. Many implementations will in fact return pointers that are aligned on multiples of 2, 4, or 8 bytes even when the required alignment isn't that coarse, because it avoids having to deal with areas of free space that are smaller than that, but unless an implementation explicitly promises that one shouldn't expect that such behavior won't change.

supercat
  • 77,689
  • 9
  • 166
  • 211
1

Microchip has confirmed via their support team that the XC16 malloc() and realloc() always return even addresses.

EBlake
  • 735
  • 7
  • 14
0

Just avoid malloc. From MISRA/C 2004:

Rule 20.4 (required): Dynamic heap memory allocation shall not be used. [Unspecified 19; Undefined 91, 92; Implementation 69; Koenig 32] This precludes the use of the functions calloc, malloc, realloc and free. There is a whole range of unspecified, undefined and implementation-defined behaviour associated with dynamic memory allocation, as well as a number of other potential pitfalls. Dynamic heap memory allocation may lead to memory leaks, data inconsistency, memory exhaustion, non- deterministic behaviour. Note that some implementations may use dynamic heap memory allocation to implement other functions (for example functions in the library string.h). If this is the case then these functions shall also be avoided.

If you know that you won't need to store more than 100 integers, just declare an array with size of 128 elements (for example).

Mr.Bitwise
  • 21
  • 2
  • “The good thing about standards is that there are so many to choose from.” -Andrew Tanenbaum The problem with that is when have, as an example, code for a buffer that's used in several places in a project. Some uses require a small buffer, some need a larger buffer. The interface can be greatly simplified by using dynamic allocation. Many safety critical applications have rules like "No malloc after initialization" or "no malloc once take-off starts." – Ryan B Dec 01 '16 at 23:41