EmbeddedRelated.com
Forums
The 2026 Embedded Online Conference

How to avoid malloc with encapsulation

Started by pozz December 21, 2016
Il 21/12/2016 18:06, Wouter van Ooijen ha scritto:
 > Op 21-Dec-16 om 12:38 PM schreef pozz:
 >> I know encapsulation tecnique is a Good Thing in coding. Encapsulation
 >> means writing write well separated modules, similar to classes in OO
 >> languages.
 >>
 >> Even in C, that isn't OO language, is possible to reach encapsulation by
 >> using a very simple ad effective trick: the instance of a "class" (C
 >> structure) is a pointer to the struct that isn't defined in .h (only
 >> typedef), but in .c.  For example, see here [1].
 >>
 >> IMHO it's a very good approach, however it's difficult to implement in
 >> embedded systems where you lack the presence of malloc (and you don't
 >> like to use it for many many reasons).
 >>
 >> The constructor/init/create function of the class/struct must allocate
 >> the space needed for the instance, but it cannot use a static allocation
 >> method (it doesn't know how many instances will be requested).
 >>
 >> One solution is to abandon encapsulation and expose the internal
 >> definition of struct in the header file. In this way, the user (of the
 >> class) can allocate directly the instance, by defining a variable.
 >>
 >> Another solution is to implement a minimalistic malloc inside the class
 >> source, maybe a simple memory pool where the number of elements are
 >> defined at compile time.
 >>
 >> Do you have better solutions?
 >
 > Use C++.
 >
 > (Just as with C, this means use *as suitable subset* of C++.)

I know C++ could be better (maybe Ada or...).  I think a discussion of 
the best programming language for embedded systems would be an entire 
different thread.

Staying on my question, how C++ helps? Of course it gives naturally 
encapsulation... but what about memory allocation and instance allocation?
On Thu, 22 Dec 2016 00:43:29 +0100, pozz wrote:

> Il 21/12/2016 18:06, Wouter van Ooijen ha scritto: > > Op 21-Dec-16 om 12:38 PM schreef pozz: > >> I know encapsulation tecnique is a Good Thing in coding. > >> Encapsulation means writing write well separated modules, similar to > >> classes in OO languages. > >> > >> Even in C, that isn't OO language, is possible to reach > >> encapsulation by using a very simple ad effective trick: the > >> instance of a "class" (C structure) is a pointer to the struct that > >> isn't defined in .h (only typedef), but in .c. For example, see > >> here [1]. > >> > >> IMHO it's a very good approach, however it's difficult to implement > >> in embedded systems where you lack the presence of malloc (and you > >> don't like to use it for many many reasons). > >> > >> The constructor/init/create function of the class/struct must > >> allocate the space needed for the instance, but it cannot use a > >> static allocation method (it doesn't know how many instances will be > >> requested). > >> > >> One solution is to abandon encapsulation and expose the internal > >> definition of struct in the header file. In this way, the user (of > >> the class) can allocate directly the instance, by defining a > >> variable. > >> > >> Another solution is to implement a minimalistic malloc inside the > >> class source, maybe a simple memory pool where the number of > >> elements are defined at compile time. > >> > >> Do you have better solutions? > > > > Use C++. > > > > (Just as with C, this means use *as suitable subset* of C++.) > > I know C++ could be better (maybe Ada or...). I think a discussion of > the best programming language for embedded systems would be an entire > different thread. > > Staying on my question, how C++ helps? Of course it gives naturally > encapsulation... but what about memory allocation and instance > allocation?
A lot of what I do in C++ is to instantiate my classes where I need them, statically in files. So, for instance, my "serial.cpp" file doesn't instantiate any serial interfaces. Instead, my "menu.cpp" instantiates an object by including "serial.h" and then making an object that takes the port number in its constructor. Wouter would have me write the serial port code such that the whole thing is a template class -- indeed, I may start doing that. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com I'm looking for work -- see my website!
On 21/12/16 22:46, Wouter van Ooijen wrote:
> Op 21-Dec-16 om 7:20 PM schreef Tim Wescott: >> On Wed, 21 Dec 2016 04:23:25 -0800, kalvin.news wrote: >> >>> keskiviikko 21. joulukuuta 2016 13.38.04 UTC+2 pozz kirjoitti: >>>> I know encapsulation tecnique is a Good Thing in coding. Encapsulation >>>> means writing write well separated modules, similar to classes in OO >>>> languages. >>>> >>>> Even in C, that isn't OO language, is possible to reach encapsulation >>>> by using a very simple ad effective trick: the instance of a "class" (C >>>> structure) is a pointer to the struct that isn't defined in .h (only >>>> typedef), but in .c. For example, see here [1]. >>>> >>>> IMHO it's a very good approach, however it's difficult to implement in >>>> embedded systems where you lack the presence of malloc (and you don't >>>> like to use it for many many reasons). >>>> >>>> The constructor/init/create function of the class/struct must allocate >>>> the space needed for the instance, but it cannot use a static >>>> allocation method (it doesn't know how many instances will be >>>> requested). >>>> >>>> One solution is to abandon encapsulation and expose the internal >>>> definition of struct in the header file. In this way, the user (of the >>>> class) can allocate directly the instance, by defining a variable. >>>> >>>> Another solution is to implement a minimalistic malloc inside the class >>>> source, maybe a simple memory pool where the number of elements are >>>> defined at compile time. >>>> >>>> Do you have better solutions? >>>> >>>> >>>> >>>> [1] https://alastairs-place.net/blog/2013/06/03/encapsulation-in-c/ >>> >>> Typically using malloc is ok during system initialization time. An >>> alternative to malloc are resource pools. Just allocate the needed >>> resources when the system is booting up. >> >> And never, ever, use free. This is what I do, even with C++. > > Me too. > > Typically I used something like > > void free( void * p ){ > void you_silly_you_are_using_free(); > you_silly_you_are_using_free(); > } > > without a definition of you_silly_you_are_using_free(). > > (That is, if I use a heap at all.) >
You can do a little better than that, by declaring free as: void __attribute__((error("Don't use free"))) free(void*); for gcc and compatible compilers, or [[deprecated("Don't use free!")]] void free(void*); for C++ 14, if you don't have gcc. That won't help if free is called indirectly, in which case you are still relying on the linker failure. But at least for your own code that can #include these declarations, you'll get an error message (or at least a "deprecated" warning) at compile time.
On 22/12/16 00:43, pozz wrote:
> Il 21/12/2016 18:06, Wouter van Ooijen ha scritto: >> Op 21-Dec-16 om 12:38 PM schreef pozz: >>> I know encapsulation tecnique is a Good Thing in coding. Encapsulation >>> means writing write well separated modules, similar to classes in OO >>> languages. >>> >>> Even in C, that isn't OO language, is possible to reach encapsulation by >>> using a very simple ad effective trick: the instance of a "class" (C >>> structure) is a pointer to the struct that isn't defined in .h (only >>> typedef), but in .c. For example, see here [1]. >>> >>> IMHO it's a very good approach, however it's difficult to implement in >>> embedded systems where you lack the presence of malloc (and you don't >>> like to use it for many many reasons). >>> >>> The constructor/init/create function of the class/struct must allocate >>> the space needed for the instance, but it cannot use a static allocation >>> method (it doesn't know how many instances will be requested). >>> >>> One solution is to abandon encapsulation and expose the internal >>> definition of struct in the header file. In this way, the user (of the >>> class) can allocate directly the instance, by defining a variable. >>> >>> Another solution is to implement a minimalistic malloc inside the class >>> source, maybe a simple memory pool where the number of elements are >>> defined at compile time. >>> >>> Do you have better solutions? >> >> Use C++. >> >> (Just as with C, this means use *as suitable subset* of C++.) > > I know C++ could be better (maybe Ada or...). I think a discussion of > the best programming language for embedded systems would be an entire > different thread. > > Staying on my question, how C++ helps? Of course it gives naturally > encapsulation... but what about memory allocation and instance allocation?
For one thing, you override "new" for different classes so that you can get a safe pool-based allocation while still using "new" in your code. For some classes, you will only ever have one of them. Such classes can have a static buffer, and use that for their "new" - that lets you have entirely statically allocated memory, but lets you use "new" to define the construction order.
Op 22-Dec-16 om 1:04 AM schreef Tim Wescott:
> On Thu, 22 Dec 2016 00:43:29 +0100, pozz wrote: > >> Il 21/12/2016 18:06, Wouter van Ooijen ha scritto: >> > Op 21-Dec-16 om 12:38 PM schreef pozz: >> >> I know encapsulation tecnique is a Good Thing in coding. >> >> Encapsulation means writing write well separated modules, similar to >> >> classes in OO languages. >> >> >> >> Even in C, that isn't OO language, is possible to reach >> >> encapsulation by using a very simple ad effective trick: the >> >> instance of a "class" (C structure) is a pointer to the struct that >> >> isn't defined in .h (only typedef), but in .c. For example, see >> >> here [1]. >> >> >> >> IMHO it's a very good approach, however it's difficult to implement >> >> in embedded systems where you lack the presence of malloc (and you >> >> don't like to use it for many many reasons). >> >> >> >> The constructor/init/create function of the class/struct must >> >> allocate the space needed for the instance, but it cannot use a >> >> static allocation method (it doesn't know how many instances will be >> >> requested). >> >> >> >> One solution is to abandon encapsulation and expose the internal >> >> definition of struct in the header file. In this way, the user (of >> >> the class) can allocate directly the instance, by defining a >> >> variable. >> >> >> >> Another solution is to implement a minimalistic malloc inside the >> >> class source, maybe a simple memory pool where the number of >> >> elements are defined at compile time. >> >> >> >> Do you have better solutions? >> > >> > Use C++. >> > >> > (Just as with C, this means use *as suitable subset* of C++.) >> >> I know C++ could be better (maybe Ada or...). I think a discussion of >> the best programming language for embedded systems would be an entire >> different thread. >> >> Staying on my question, how C++ helps? Of course it gives naturally >> encapsulation... but what about memory allocation and instance >> allocation? > > A lot of what I do in C++ is to instantiate my classes where I need them, > statically in files. > > So, for instance, my "serial.cpp" file doesn't instantiate any serial > interfaces. Instead, my "menu.cpp" instantiates an object by including > "serial.h" and then making an object that takes the port number in its > constructor. > > Wouter would have me write the serial port code such that the whole thing > is a template class -- indeed, I may start doing that.
Only when it needs parametrization. Wouter "Objects? No Thanks!" van Ooijen
On 12/21/16 6:38 AM, pozz wrote:
> I know encapsulation tecnique is a Good Thing in coding. Encapsulation > means writing write well separated modules, similar to classes in OO > languages. > > Even in C, that isn't OO language, is possible to reach encapsulation by > using a very simple ad effective trick: the instance of a "class" (C > structure) is a pointer to the struct that isn't defined in .h (only > typedef), but in .c. For example, see here [1]. > > IMHO it's a very good approach, however it's difficult to implement in > embedded systems where you lack the presence of malloc (and you don't > like to use it for many many reasons). > > The constructor/init/create function of the class/struct must allocate > the space needed for the instance, but it cannot use a static allocation > method (it doesn't know how many instances will be requested). > > One solution is to abandon encapsulation and expose the internal > definition of struct in the header file. In this way, the user (of the > class) can allocate directly the instance, by defining a variable. > > Another solution is to implement a minimalistic malloc inside the class > source, maybe a simple memory pool where the number of elements are > defined at compile time. > > Do you have better solutions? > > > > [1] https://alastairs-place.net/blog/2013/06/03/encapsulation-in-c/
One technique that I have seen/used is the header that defines the opaque type also defines a structure that has been built to have the same alignment and size as the original, but not the 'real' definition (perhaps just a largest object then an array of char, or the right types but 'ugly' names (dummy1, dummy2, etc), and a check that its size matches in the real implementation file. That way client code can create a static object to pass to the init function that will have the right size, but the client code can't easily access the structure members.
The 2026 Embedded Online Conference