Dynamic memory allocation in embedded C - c

Can I use functions malloc and delete in embedded C? For example, I have one function, where was created pointer on structure with function malloc. This function return address in ram and I can use this . After exit from my function, where memory was allocated, this pointer will be deleted or this memory reserved for this, while not will be function delete terminated ?
Typedef struct {
Char varA;
Char varB
} myStruct ;
Void myfunc ( void)
{
myStruct * ptrStruct = ( myStruct *) malloc ( sizeof (myStruct)) ;
// Code here
//........
return ;
}

Generally, you shouldn't be using malloc in embedded systems, because doing so doesn't make any sense as explained here. In particular, it doesn't make any sense what-so-ever to use it on bare metal systems.
The only place where it makes sense to use dynamic memory allocation is large hosted, multi-process systems where multiple processes share the same RAM. If your definition of an embedded system is an Android smart phone or a portable PC, then yes it is fine to use malloc.
If you find yourself using it anywhere else, it almost certainly means that your program design is fundamentally flawed and also that you don't know how a heap works.
In addition, almost every embedded systems programming standard bans dynamic memory allocation.

There is nothing specific about embedded systems that prevent the use of dynamic memory.
However you may need to provide support for it in a number of ways, for example:
You need to ensure that the linker allocates sufficient space for the dynamic heap. Some linker scripts may already automatically allocate all remaining memory to the heap after stack and any other reserved allocations.
You may need to implement low level stubs to allow the library to access heap memory - for example in the newlib library, you need to implement sbrk_r() for malloc() etc. to work correctly.
In a multi-threaded system you may need to implement mutex stubs to ensure safe heap allocation. If the library does not provide such stubs, then malloc()/free() etc. will not be safe to use in such an environment, and you should write wrapper functions that assert the locks externally.
There are a number of reasons however why you might choose to avoid using dynamic memory (or at least standard library implemented dynamic memory) in an embedded system however:
Standard allocation schemes have non-deterministic timing unsuited to hard-real-time systems.
You need to handle the possibility of allocation failure gracefully for every allocation. Handling a potential non-deterministic run-time error safely is more complex than simply having the compiler tell you have insufficient memory at build time.
You need to guard against memory leaks; true of any system, but with no OS to manage memory exhaustion and kill a leaking process how will your system behave?
The standard library heap management may not be thread-safe without mutex stubs or wrapper functions.
Bugs that corrupt the heap are unlikely to affect execution immediately, often only causing an observable failure when a new heap operation is performed, resulting in non-deterministic behaviour at a time and location unrelated to the actual cause - making them very hard to diagnose. Again this is true of any system, but the debug facilities in a cross-hosted embedded system are often less sophisticated that on a self-hosted system.

Yes, you can use malloc in embedded C. Some embedded systems have its own encapsulated memory allocation APIs. malloc() is the C lib API.
The memory is allocated from heap, a dedicated memory range defined by system designer. If you did not free the allocated memory after your function exits, the allocated memory is reserved and other processes cannot use it. Typically, it is memory leak. If you free the allocated memory but you still use the pointer after that, it is a wild pointer and will cause unknown behaviour.

Related

Does malloc needs OS support?

Memory management is a service provided by underlying operating system. When we call malloc()/free() and there's no operating systems running(for example a bare metal embedded system), how is the memory allocation and tracking handled?
There should be an entity that tracks which addresses are free and which are not. That's OS memory management unit. malloc()/free() will then have to call OS system calls. So no OS means no malloc()/free(). Am I wrong in assuming this?
Update:
All answers pointed out that malloc/free can use either static pool allocation(when no OS is available) or use sbrk/brk which are kernel system calls. Question is how does the malloc/free knows if there's a kernel beneath or not?
Answer(see comment by "Kuba Ober" under his answer below):
malloc doesn't need to know anything, because the C library that you link your project with is specific to the target: if you develop for Linux, you use a C library for Linux, different than when you develop for OS X, or Windows, or bare bones ARM Cortex M0. Or, heck, barebones x86. It's people who write the C library that know how to implement it so that it works on the desired target. For example, a barebones C library for x86 would use EFI and ACPI to query the list of available blocks of RAM unused by hardware nor BIOS, and then use those in fulfilling allocation requests.
malloc() and free() do not require OS support. They can be (and often are!) implemented on bare-metal systems. For example, the Arduino library uses malloc() and free() to manage strings.
In hosted implementations (that is, an application running on an operating system), malloc() and free() will typically use operating system services to allocate new "hunks" of memory -- often as much as a few megabytes at a time -- and to return those hunks to the operating system when they are unused. Smaller allocations are handled by cutting those blocks of memory into the sizes needed by an application. This allows small allocations to be managed without the overhead of a system call.
In an unhosted implementation (like a bare-metal system), the application already has access to all memory in existence on the system, and can parcel out chunks of that memory however it likes.
At a lower level: both hosted and unhosted implementations of malloc() often work by treating each allocated or unallocated block of memory as an entry in a linked list. This is typically accomplished by storing a structure immediately before the start of each allocation, e.g.
struct malloc_block {
struct malloc_block *prev, *next;
size_t size;
...
char allocation[];
};
and returning a pointer to allocation as the return value of malloc(). Functions like realloc() and free() can retrieve the structure by subtracting the size of the structure from a pointer to the allocation.
The Malloc/free function manage a pool of memory. These functions are generally not operating system services.
How then is that pool created?
On most systems, malloc calls operating system services to map pages into the the process address space to create and expand the memory pool. If you call malloc, and no memory is available, most implementations will call a system service to map more memory and expand the pool.
The malloc implementation needs to maintain data structures that keep track of what memory in the pool is free and what has been allocated. This is done in many different ways. It is not unusual for programmers to select a malloc/free combination that works best for them and link it into their application.
So, yes there is operating system involvement—generally.
But you asked about whether they can be implemented without an operating system.
Suppose you did:
static char pool [POOLSIZE] ;
in your malloc implementation. Then you would not require a system service to create the pool during execution time. On the other hand, your pool has a fixed size.
Generally speaking: no, or at least not at runtime, if we define runtime as the moments between main() entering and returning.
Suppose you implement malloc that operates on a fixed-size pool:
static char pool[MALLOC_POOL_SIZE];
void *malloc(size_t size) {
…
}
void free(void *block) {
…
}
Then, on both hosted- and unhosted implementations you have working dynamic memory allocation. On hosted implementations, the binary loader will ensure that there’s memory mapped behind the pool. On unhosted implementations, the linker will pre-locate the pool in available RAM, and linking will fail if the pool is too large.
So no, in general no OS involvement is needed once your code is running, but OS involvement is needed to get your code to run in the first place (if there is an OS).
And of course, “not needed” means not necessary, but doesn’t exclude OS support for dynamic memory allocation in a particular C runtime library. In most hosted runtimes, malloc uses a pool that’s dynamically expanded (and perhaps contracted) by invoking relevant OS APIs. On classic Unix, the expansion would be done via the brk syscall.

Does malloc itself provide some kind of synchronization?

I heard "malloc is thread-safe because it provide a synchronization primitive so that simultaneous to malloc will not corrupt the heap".
But when I look at the source code of malloc function in visual studio crt, it turns out that the malloc function just pass the request to syscall HeapAlloc. So I think it is the opearting system itself provide some kind of synchronization to protect application from corrupted heap rather than malloc.
Then what about linux? Does malloc itself provide some kind of synchronization?
The only standard that speaks about this is C11 (since there was no notion of multithreading before), which says (7.22.3/2):
For purposes of determining the existence of a data race, memory allocation functions
behave as though they accessed only memory locations accessible through their
arguments and not other static dura­tion storage. These functions may, however, visibly
modify the storage that they allocate or de­allo­cate. A call to free or realloc that
deallocates a region p of memory synchronizes with any allocation call that allocates all
or part of the region p. This synchronization occurs after any access of p by the
deallocating function, and before any such access by the allocating function.
In short, "it's all fine".
However, specific implementations like Linux will surely have been providing their own, strong guarantees for a long time (since ptmalloc2 I think), and it's basically always been fine. [Update, thanks to #ArjunShankar: Posix does indeed require that malloc be thread-safe.]
(Note, though, that other implementations such as Google's tcmalloc may have better performance in multithreaded applications.)
(For C++, see C++11: 18.6.1.4.)

malloc in an embedded system without an operating system

This query is regarding allocation of memory using malloc.
Generally what we say is malloc allocates memory from heap.
Now say I have a plain embedded system(No operating system), I have normal program loaded where I do malloc in my program.
In this case where is the memory allocated from ?
malloc() is a function that is usually implemented by the runtime-library. You are right, if you are running on top of an operating system, then malloc will sometimes (but not every time) trigger a system-call that makes the OS map some memory into your program's address space.
If your program runs without an operating system, then you can think of your program as being the operating system. You have access to all addresses, meaning you can just assign an address to a pointer, then de-reference that pointer to read/write.
Of course you have to make sure that not other parts of your program just use the same memory, so you write your own memory-manager:
To put it simply you can set-aside a range of addresses which your "memory-manager" uses to store which address-ranges are already in use (the datastructures stored in there can be as easy as a linked list or much much more complex). Then you will write a function and call it e.g. malloc() which forms the functional part of your memory-manager. It looks into the mentioned datastructure to find an address of ranges that is as long as the argument specifies and return a pointer to it.
Now, if every function in your program calls your malloc() instead of randomly writing into custom addresses you've done the first step. You can write a free()-function which will look for the pointer it is given in the mentioned datastructure, and adapts the datastructure (in the naive linked-list it would merge two links).
The only real answer is "Wherever your compiler/library-implementation puts it".
In the embedded system I use, there is no heap, since we haven't written one.
From the heap as you say. The difference is that the heap is not provided by the OS. Your application's linker script will no doubt include an allocation for the heap. The run-time library will manage this.
In the case of the Newlib C library often used in GCC based embedded systems not running an OS or at least not running Linux, the library has a stub syscall function called sbrk(). It is the respnsibility of the developer to implement sbrk(), which must provide more memory the the heap manager on request. Typically it merely increments a pointer and returns a pointer to the start of the new block, thereafter the library's heap manager manages and maintains the new block which may or may not be contiguous with previous blocks. The previous link includes an example implementation.

C - Design your own free( ) function

Today, I appeared for an interview and the interviewer asked me this,
Tell me the steps how will you design your own free( ) function for
deallocate the allocated memory.
How can it be more efficient than C's default free() function ? What can you conclude ?
I was confused, couldn't think of the way to design.
What do you think guys ?
EDIT : Since we need to know about how malloc() works, can you tell me the steps to write our own malloc() function
That's actually a pretty vague question, and that's probably why you got confused. Does he mean, given an existing malloc implementation, how would you go about trying to develop a more efficient way to free the underlying memory? Or was he expecting you to start discussing different kinds of malloc implementations and their benefits and problems? Did he expect you to know how virtual memory functions on the x86 architecture?
Also, by more efficient, does he mean more space efficient or more time efficient? Does free() have to be deterministic? Does it have to return as much memory to the OS as possible because it's in a low-memory, multi-tasking environment? What's our criteria here?
It's hard to say where to start with a vague question like that, other than to start asking your own questions to get clarification. After all, in order to design your own free function, you first have to know how malloc is implemented. So chances are, the question was really about whether or not you knew anything about how malloc can be implemented.
If you're not familiar with the internals of memory management, the easiest way to get started with understanding how malloc is implemented is to first write your own.
Check out this IBM DeveloperWorks article called "Inside Memory Management" for starters.
But before you can write your own malloc/free, you first need memory to allocate/free. Unfortunately, in a protected mode OS, you can't directly address the memory on the machine. So how do you get it?
You ask the OS for it. With the virtual memory features of the x86, any piece of RAM or swap memory can be mapped to a memory address by the OS. What your program sees as memory could be physically fragmented throughout the entire system, but thanks to the kernel's virtual memory manager, it all looks the same.
The kernel usually provides system calls that allow you to map in additional memory for your process. On older UNIX OS's this was usually brk/sbrk to grow heap memory onto the edge of your process or shrink it off, but a lot of systems also provide mmap/munmap to simply map a large block of heap memory in. It's only once you have access to a large, contiguous looking block of memory that you need malloc/free to manage it.
Once your process has some heap memory available to it, it's all about splitting it into chunks, with each chunk containing its own meta information about its size and position and whether or not it's allocated, and then managing those chunks. A simple list of structs, each containing some fields for meta information and a large array of bytes, could work, in which case malloc has to run through the list until if finds a large enough unallocated chunk (or chunks it can combine), and then map in more memory if it can't find a big enough chunk. Once you find a chunk, you just return a pointer to the data. free() can then use that pointer to reverse back a few bytes to the member fields that exist in the structure, which it can then modify (i.e. marking chunk.allocated = false;). If there's enough unallocated chunks at the end of your list, you can even remove them from the list and unmap or shrink that memory off your process's heap.
That's a real simple method of implementing malloc though. As you can imagine, there's a lot of possible ways of splitting your memory into chunks and then managing those chunks. There's as many ways as there are data structures and algorithms. They're all designed for different purposes too, like limiting fragmentation due to small, allocated chunks mixed with small, unallocated chunks, or ensuring that malloc and free run fast (or sometimes even more slowly, but predictably slowly). There's dlmalloc, ptmalloc, jemalloc, Hoard's malloc, and many more out there, and many of them are quite small and succinct, so don't be afraid to read them. If I remember correctly, "The C Programming Language" by Kernighan and Ritchie even uses a simple malloc implementation as one of their examples.
You can't blindly design free() without knowing how malloc() works under the hood because your implementation of free() would need to know how to manipulate the bookkeeping data and that's impossible without knowing how malloc() is implemented.
So an unswerable question could be how you would design malloc() and free() instead which is not a trivial question but you could answer it partially for example by proposing some very simple implementation of a memory pool that would not be equivalent to malloc() of course but would indicate your presence of knowledge.
One common approach when you only have access to user space (generally known as memory pool) is to get a large chunk of memory from the OS on application start-up. Your malloc needs to check which areas of the right size of that pool are still free (through some data structure) and hand out pointers to that memory. Your free needs to mark the memory as free again in the data structure and possibly needs to check for fragmentation of the pool.
The benefits are that you can do allocation in nearly constant time, the drawback is that your application consumes more memory than actually is needed.
Tell me the steps how will you design your own free( ) function for deallocate the allocated memory.
#include <stdlib.h>
#undef free
#define free(X) my_free(X)
inline void my_free(void *ptr) { }
How can it be more efficient than C's default free() function ?
It is extremely fast, requiring zero machine cycles. It also makes use-after-free bugs go away. It's a very useful free function for use in programs which are instantiated as short-lived batch processes; it can usefully be deployed in some production situations.
What can you conclude ?
I really want this job, but in another company.
Memory usage patterns could be a factor. A default implementation of free can't assume anything about how often you allocate/deallocate and what sizes you allocate when you do.
For example, if you frequently allocate and deallocate objects that are of similar size, you could gain speed, memory efficiency, and reduced fragmentation by using a memory pool.
EDIT: as sharptooth noted, only makes sense to design free and malloc together. So the first thing would be to figure out how malloc is implemented.
malloc and free only have a meaning if your app is to work on top of an OS. If you would like to write your own memory management functions you would have to know how to request the memory from that specific OS or you could reserve the heap memory right away using existing malloc and then use your own functions to distribute/redistribute the allocated memory through out your app
There is an architecture that malloc and free are supposed to adhere to -- essentially a class architecture permitting different strategies to coexist. Then the version of free that is executed corresponds to the version of malloc used.
However, I'm not sure how often this architecture is observed.
The knowledge of working of malloc() is necessary to implement free(). You can find a implementation of malloc() and free() using the sbrk() system call in K&R The C Programming Language Chapter 8, Section 8.7 "Example--A Storage Allocator" pp.185-189.

How can I access heap memory beside using malloc?

Is there a way that you can assign memory from heap without a call to malloc?
Can the following call be affective for it?
void* loc = (void*) &heap[end_of_heap];
No. The C language itself provides no such functionality. If you only care about Unix systems conforming to a deprecated feature of an old version of the Unix standard (SUSv2 or earlier, if I remember correctly), the brk and sbrk functions provide this functionality. But you really should not use it unless you're writing very low-level code that will never need to be portable.
There is no portable way besides malloc and friends, but if you're willing to get platform-specific sbrk (and brk) in old-fashioned Unix (not in current Posix), used to be the underlying syscalls. Now their manpage says
Avoid using brk() and sbrk(): the
malloc(3) memory allocation package is
the
portable and comfortable way of allocating memory.
and that advice is surely good (no real advantage in using the old-fashioned syscalls even in platforms that supply them). mmap of some /dev/ is a totally different way for some modern Unix versions, Windows has its own totally different "win32 API calls" for the purpose, and so on.
There is no way to get a pointer to new and valid heap memory other than using a heap allocating function. You cannot simply add a pointer into the heap at the end of an existing pointer and expect to reliably access it.
The Standard does not say anything about heap (search it, if you don't believe this). An implementation is not even required to have a heap (as we commonly know it).
However, the short answer to your question is, no in Standard C. Unless of course you use a platform specific API. Typically, OS APIs sometimes do give you some leeway as to accessing memory.
You cannot access heap reliably without malloc, but there are alternatives for memory allocation.
If you're trying to get finer control over memory allocations, you can use other memory managers like bget memory allocator. Here you grab a huge chunk of heap (the maximum memory requiredment anticipated + some overhead) using malloc and pass it to the bget using bpool. From there on, call bget instead of malloc to allocate memory and brel to free it. bget is reportedly better in avoiding memory fragmentation.

Resources