Heap allocation on a microcontrollerPC shares memory with external microcontrollerMicrocontroller on-chip flash consumption - size matters?Interfacing USB with a microcontrollerInductor near the microcontrollerSTM32 Mass Storage with 8K allocation unit sizeSTM Microcontroller burns every timeLinker script and data allocation

What are some examples of three-mora atamadaka verbs besides 帰る?

How to initiate a conversation with a person who recently had transition but you were not in touch with them?

VM with Windows Server won't boot after restoring from ghettoVCB backup

Is there a problem using A LOT of locks in a process?

How do I build a kernel using patches from LKML?

Can I select any of my published paper in journal for book chapter

Using parent's property and will as evidence of assets

Right way to say I disagree with the design but ok I will do

How does the Gameboy Link Cable work?

Chromatic abberation in lens

Impeachment jury tampering

How does an aircraft descend without its nose pointing down?

18-month-old kicked out of church nursery

refreshApex in lwc doesn't seem to work

How to help my son improve without being discouraging?

How can I find the weakness of our "Quality Assurance Process"?

Can only rich people become president?

Electric field due to a hydrogen atom

Continents with simplex noise

How is warfare affected when armor has (temporarily) outpaced guns? How can guns compete?

How did the T-850 still function after it removed its second battery?

Disable the use of the "com.apple.quarantine" extended attribute on Mojave

Gradients - complex shape - Illustrator

Echo bracket symbol to terminal



Heap allocation on a microcontroller


PC shares memory with external microcontrollerMicrocontroller on-chip flash consumption - size matters?Interfacing USB with a microcontrollerInductor near the microcontrollerSTM32 Mass Storage with 8K allocation unit sizeSTM Microcontroller burns every timeLinker script and data allocation






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









4














$begingroup$


I'm working on STM32F303VC. How does the heap allocation work?



When I declare the arrays outside main() it allocates them on the heap - SRAM - 0x2000000 and forth in this MCU. But what determines the size of the heap? (And hence its overflow.)



There are two options:




  1. In the 'startup_stm32f30x.s' file I see that:



    Heap_Size EQU 0x00000200 // Which is only 1K!


    [See here: [http://www.keil.com/support/man/docs/armlib/armlib_chr1358938939461.htm. Anyway, I just used the default file from STM's library]



  2. But on the target configurations options, the R/W memory area is declared to be a size of 0x8000 (which is 32K).


So I checked this in the debugger:



uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30 kilobytes

int main(void)

_xValH[4999] = 0x4;
_xValL[4999] = 0x5;
_xVal[4999] = 0x6;



This didn't throw an exception - which means that it is the second option of the above. But furthermore, even if I go above the 32K - say:



uint16_t _xValH[6000];
uint16_t _xValL[6000];
uint16_t _xVal[6000];
//3*6000*2 bytes each = 36 kilobytes

int main(void)

_xValH[5999] = 0x4;
_xValL[5999] = 0x5;
_xVal[5999] = 0x6;



It's still working! The only time it throws me to exception is when I surpass the 40K - which is the limit of the SRAM (0x20009FFF).



So, what is the meaning of the A line code? And the meaning of the size I enter in B?










share|improve this question












$endgroup$














  • $begingroup$
    If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
    $endgroup$
    – AaronD
    Jun 7 at 3:31










  • $begingroup$
    In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
    $endgroup$
    – Peter Mortensen
    Jun 7 at 8:50











  • $begingroup$
    @AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
    $endgroup$
    – Elad
    Jun 7 at 12:22










  • $begingroup$
    @Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
    $endgroup$
    – AaronD
    Jun 7 at 17:58










  • $begingroup$
    @AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
    $endgroup$
    – Elad
    Jun 10 at 7:46


















4














$begingroup$


I'm working on STM32F303VC. How does the heap allocation work?



When I declare the arrays outside main() it allocates them on the heap - SRAM - 0x2000000 and forth in this MCU. But what determines the size of the heap? (And hence its overflow.)



There are two options:




  1. In the 'startup_stm32f30x.s' file I see that:



    Heap_Size EQU 0x00000200 // Which is only 1K!


    [See here: [http://www.keil.com/support/man/docs/armlib/armlib_chr1358938939461.htm. Anyway, I just used the default file from STM's library]



  2. But on the target configurations options, the R/W memory area is declared to be a size of 0x8000 (which is 32K).


So I checked this in the debugger:



uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30 kilobytes

int main(void)

_xValH[4999] = 0x4;
_xValL[4999] = 0x5;
_xVal[4999] = 0x6;



This didn't throw an exception - which means that it is the second option of the above. But furthermore, even if I go above the 32K - say:



uint16_t _xValH[6000];
uint16_t _xValL[6000];
uint16_t _xVal[6000];
//3*6000*2 bytes each = 36 kilobytes

int main(void)

_xValH[5999] = 0x4;
_xValL[5999] = 0x5;
_xVal[5999] = 0x6;



It's still working! The only time it throws me to exception is when I surpass the 40K - which is the limit of the SRAM (0x20009FFF).



So, what is the meaning of the A line code? And the meaning of the size I enter in B?










share|improve this question












$endgroup$














  • $begingroup$
    If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
    $endgroup$
    – AaronD
    Jun 7 at 3:31










  • $begingroup$
    In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
    $endgroup$
    – Peter Mortensen
    Jun 7 at 8:50











  • $begingroup$
    @AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
    $endgroup$
    – Elad
    Jun 7 at 12:22










  • $begingroup$
    @Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
    $endgroup$
    – AaronD
    Jun 7 at 17:58










  • $begingroup$
    @AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
    $endgroup$
    – Elad
    Jun 10 at 7:46














4












4








4





$begingroup$


I'm working on STM32F303VC. How does the heap allocation work?



When I declare the arrays outside main() it allocates them on the heap - SRAM - 0x2000000 and forth in this MCU. But what determines the size of the heap? (And hence its overflow.)



There are two options:




  1. In the 'startup_stm32f30x.s' file I see that:



    Heap_Size EQU 0x00000200 // Which is only 1K!


    [See here: [http://www.keil.com/support/man/docs/armlib/armlib_chr1358938939461.htm. Anyway, I just used the default file from STM's library]



  2. But on the target configurations options, the R/W memory area is declared to be a size of 0x8000 (which is 32K).


So I checked this in the debugger:



uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30 kilobytes

int main(void)

_xValH[4999] = 0x4;
_xValL[4999] = 0x5;
_xVal[4999] = 0x6;



This didn't throw an exception - which means that it is the second option of the above. But furthermore, even if I go above the 32K - say:



uint16_t _xValH[6000];
uint16_t _xValL[6000];
uint16_t _xVal[6000];
//3*6000*2 bytes each = 36 kilobytes

int main(void)

_xValH[5999] = 0x4;
_xValL[5999] = 0x5;
_xVal[5999] = 0x6;



It's still working! The only time it throws me to exception is when I surpass the 40K - which is the limit of the SRAM (0x20009FFF).



So, what is the meaning of the A line code? And the meaning of the size I enter in B?










share|improve this question












$endgroup$




I'm working on STM32F303VC. How does the heap allocation work?



When I declare the arrays outside main() it allocates them on the heap - SRAM - 0x2000000 and forth in this MCU. But what determines the size of the heap? (And hence its overflow.)



There are two options:




  1. In the 'startup_stm32f30x.s' file I see that:



    Heap_Size EQU 0x00000200 // Which is only 1K!


    [See here: [http://www.keil.com/support/man/docs/armlib/armlib_chr1358938939461.htm. Anyway, I just used the default file from STM's library]



  2. But on the target configurations options, the R/W memory area is declared to be a size of 0x8000 (which is 32K).


So I checked this in the debugger:



uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30 kilobytes

int main(void)

_xValH[4999] = 0x4;
_xValL[4999] = 0x5;
_xVal[4999] = 0x6;



This didn't throw an exception - which means that it is the second option of the above. But furthermore, even if I go above the 32K - say:



uint16_t _xValH[6000];
uint16_t _xValL[6000];
uint16_t _xVal[6000];
//3*6000*2 bytes each = 36 kilobytes

int main(void)

_xValH[5999] = 0x4;
_xValL[5999] = 0x5;
_xVal[5999] = 0x6;



It's still working! The only time it throws me to exception is when I surpass the 40K - which is the limit of the SRAM (0x20009FFF).



So, what is the meaning of the A line code? And the meaning of the size I enter in B?







stm32 memory






share|improve this question
















share|improve this question













share|improve this question




share|improve this question








edited Jun 7 at 10:52









Peter Mortensen

1,5743 gold badges14 silver badges22 bronze badges




1,5743 gold badges14 silver badges22 bronze badges










asked Jun 6 at 10:24









EladElad

234 bronze badges




234 bronze badges














  • $begingroup$
    If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
    $endgroup$
    – AaronD
    Jun 7 at 3:31










  • $begingroup$
    In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
    $endgroup$
    – Peter Mortensen
    Jun 7 at 8:50











  • $begingroup$
    @AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
    $endgroup$
    – Elad
    Jun 7 at 12:22










  • $begingroup$
    @Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
    $endgroup$
    – AaronD
    Jun 7 at 17:58










  • $begingroup$
    @AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
    $endgroup$
    – Elad
    Jun 10 at 7:46

















  • $begingroup$
    If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
    $endgroup$
    – AaronD
    Jun 7 at 3:31










  • $begingroup$
    In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
    $endgroup$
    – Peter Mortensen
    Jun 7 at 8:50











  • $begingroup$
    @AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
    $endgroup$
    – Elad
    Jun 7 at 12:22










  • $begingroup$
    @Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
    $endgroup$
    – AaronD
    Jun 7 at 17:58










  • $begingroup$
    @AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
    $endgroup$
    – Elad
    Jun 10 at 7:46
















$begingroup$
If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
$endgroup$
– AaronD
Jun 7 at 3:31




$begingroup$
If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
$endgroup$
– AaronD
Jun 7 at 3:31












$begingroup$
In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
$endgroup$
– Peter Mortensen
Jun 7 at 8:50





$begingroup$
In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
$endgroup$
– Peter Mortensen
Jun 7 at 8:50













$begingroup$
@AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
$endgroup$
– Elad
Jun 7 at 12:22




$begingroup$
@AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
$endgroup$
– Elad
Jun 7 at 12:22












$begingroup$
@Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
$endgroup$
– AaronD
Jun 7 at 17:58




$begingroup$
@Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
$endgroup$
– AaronD
Jun 7 at 17:58












$begingroup$
@AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
$endgroup$
– Elad
Jun 10 at 7:46





$begingroup$
@AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
$endgroup$
– Elad
Jun 10 at 7:46











5 Answers
5






active

oldest

votes


















17
















$begingroup$

You misunderstand what the heap is.

The heap is the area where malloc gives you blocks of RAM dynamically at run-time.

Your globally scoped, statically allocated variables & arrays are not 'on the heap'.

If you're not using malloc or any of its variants in your program, you can quite safely set the heap size to 0.






share|improve this answer










$endgroup$














  • $begingroup$
    Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
    $endgroup$
    – Elad
    Jun 7 at 12:17



















5
















$begingroup$

Those are global variables. Which generally are not allocated on either stack or heap. Exactly where they are is a longer discussion.



Your heap space is for 'globally accessible' variables created during run time. Which is different to global variables, which are allocated before your main() function is entered. Heap space variables can be allocated, de-allocated, reallocated and resized. A global variable you're generally stuck with for the entire program execution.



Your stack space is for local variables. Anything put on it by a function will be removed when the function returns.



While some implementations may put some global variables at the base of the stack, it certainly isn't a rule.






share|improve this answer










$endgroup$






















    1
















    $begingroup$

    Consider:



    uint16_t _xValH[5000];
    uint16_t _xValL[5000];
    uint16_t _xVal[5000];
    //3*5000*2 bytes each = 30Kbytes

    int main(void) {


    These are global variable declarations. These declarations reserve permanent static space in RAM. The heap is for dynamic allocations in memory.






    share|improve this answer












    $endgroup$






















      0
















      $begingroup$

      The Standard does not require freestanding implementations to provide any sort of heap. In some cases, they will pre-allocate a certain amount of space for use by the malloc() family of functions, with such space being essentially wasted if no such functions are ever used. In other cases, the compiler will reserve a certain amount of RAM for the stack and then make available to malloc() all storage that isn't and won't be used for any other purpose. In still other cases, an implementation won't provide malloc() but will provide the starting and ending address of a range of storage that the implementation has been told the hardware has, but which the implementation itself has no use for; a user application may then subdivide this range of addresses via whatever means it sees fit.



      In many cases, the latter approach is the best, because user-written allocation functions can offer finer control over allocations and fallback logic than malloc(). For example, it may be useful to determine, before performing a bunch of allocations, whether all can be guaranteed to succeed (eliminating the need to gracefully recover from an allocation failure in the middle of a task). While malloc() provides no such flexibility, user-written allocation functions can.






      share|improve this answer










      $endgroup$














      • $begingroup$
        "The Standard" can refer to a very large number of documents. Please say which standard you are referring.
        $endgroup$
        – Stig Hemmer
        Jun 7 at 7:38










      • $begingroup$
        The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
        $endgroup$
        – supercat
        Jun 7 at 15:18



















      0
















      $begingroup$

      I hope this should clear things up. It examples the different method of memory allocation in standard C.



      #include <stdint.h>
      #include <stdlib.h>
      #include <stm32f30x.h>

      uint32_t static_allocation;

      int main(void)
      uint32_t stack_allocation;
      static uint32_t private_static_allocation;
      uint32_t *heap_allocation;

      heap_allocation = malloc(4);

      static_allocation = 0x11111111;
      stack_allocation = 0x22222222;
      private_static_allocation = 0x33333333;
      *heap_allocation = 0x44444444;

      while(1)
      // Stop simulation here
      __BKPT(0);
      // remove not referenced warnings
      (void)static_allocation;
      (void)stack_allocation;
      (void)private_static_allocation;
      (void)heap_allocation;


      free(heap_allocation);



      A quick glimpse at symbol table the ARM Linker generously created shows:



      private_static_allocation 0x20000004 Data 4 main.o(.data)
      static_allocation 0x20000000 Data 4 main.o(.data)


      Which means the linker knows, at compile time, where these variables will live.

      Including the following objects in memory map:



      0x20000010 0x00000200 Zero RW 2 HEAP startup_stm32f30x.o
      0x20000210 0x00000400 Zero RW 1 STACK startup_stm32f30x.o


      And to check it really works like this, simulation debugger shows:



      enter image description here



      Notice stack_allocation isn't on the actual stack yet, but in a register. This is due to the small amount of variables in this example. Even with -O0 the compiler optimizes stack variables.



      Also notice the place of 0x11.., 0x22.. with 0x44.. being inside the heap object.

      But no other objects are in here. This means that you can safely reduce heap to 0 if you do not use malloc. Some library functions do implicitly.



      Both heap and stack overflow are not warned about during compilation since they are runtime errors.




      Relevant documentations: __use_no_heap.






      share|improve this answer












      $endgroup$
















        Your Answer






        StackExchange.ifUsing("editor", function ()
        return StackExchange.using("schematics", function ()
        StackExchange.schematics.init();
        );
        , "cicuitlab");

        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "135"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader:
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        ,
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );














        draft saved

        draft discarded
















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f442239%2fheap-allocation-on-a-microcontroller%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown


























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        17
















        $begingroup$

        You misunderstand what the heap is.

        The heap is the area where malloc gives you blocks of RAM dynamically at run-time.

        Your globally scoped, statically allocated variables & arrays are not 'on the heap'.

        If you're not using malloc or any of its variants in your program, you can quite safely set the heap size to 0.






        share|improve this answer










        $endgroup$














        • $begingroup$
          Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
          $endgroup$
          – Elad
          Jun 7 at 12:17
















        17
















        $begingroup$

        You misunderstand what the heap is.

        The heap is the area where malloc gives you blocks of RAM dynamically at run-time.

        Your globally scoped, statically allocated variables & arrays are not 'on the heap'.

        If you're not using malloc or any of its variants in your program, you can quite safely set the heap size to 0.






        share|improve this answer










        $endgroup$














        • $begingroup$
          Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
          $endgroup$
          – Elad
          Jun 7 at 12:17














        17














        17










        17







        $begingroup$

        You misunderstand what the heap is.

        The heap is the area where malloc gives you blocks of RAM dynamically at run-time.

        Your globally scoped, statically allocated variables & arrays are not 'on the heap'.

        If you're not using malloc or any of its variants in your program, you can quite safely set the heap size to 0.






        share|improve this answer










        $endgroup$



        You misunderstand what the heap is.

        The heap is the area where malloc gives you blocks of RAM dynamically at run-time.

        Your globally scoped, statically allocated variables & arrays are not 'on the heap'.

        If you're not using malloc or any of its variants in your program, you can quite safely set the heap size to 0.







        share|improve this answer













        share|improve this answer




        share|improve this answer










        answered Jun 6 at 12:42









        brhansbrhans

        10.5k2 gold badges25 silver badges33 bronze badges




        10.5k2 gold badges25 silver badges33 bronze badges














        • $begingroup$
          Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
          $endgroup$
          – Elad
          Jun 7 at 12:17

















        • $begingroup$
          Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
          $endgroup$
          – Elad
          Jun 7 at 12:17
















        $begingroup$
        Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
        $endgroup$
        – Elad
        Jun 7 at 12:17





        $begingroup$
        Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
        $endgroup$
        – Elad
        Jun 7 at 12:17














        5
















        $begingroup$

        Those are global variables. Which generally are not allocated on either stack or heap. Exactly where they are is a longer discussion.



        Your heap space is for 'globally accessible' variables created during run time. Which is different to global variables, which are allocated before your main() function is entered. Heap space variables can be allocated, de-allocated, reallocated and resized. A global variable you're generally stuck with for the entire program execution.



        Your stack space is for local variables. Anything put on it by a function will be removed when the function returns.



        While some implementations may put some global variables at the base of the stack, it certainly isn't a rule.






        share|improve this answer










        $endgroup$



















          5
















          $begingroup$

          Those are global variables. Which generally are not allocated on either stack or heap. Exactly where they are is a longer discussion.



          Your heap space is for 'globally accessible' variables created during run time. Which is different to global variables, which are allocated before your main() function is entered. Heap space variables can be allocated, de-allocated, reallocated and resized. A global variable you're generally stuck with for the entire program execution.



          Your stack space is for local variables. Anything put on it by a function will be removed when the function returns.



          While some implementations may put some global variables at the base of the stack, it certainly isn't a rule.






          share|improve this answer










          $endgroup$

















            5














            5










            5







            $begingroup$

            Those are global variables. Which generally are not allocated on either stack or heap. Exactly where they are is a longer discussion.



            Your heap space is for 'globally accessible' variables created during run time. Which is different to global variables, which are allocated before your main() function is entered. Heap space variables can be allocated, de-allocated, reallocated and resized. A global variable you're generally stuck with for the entire program execution.



            Your stack space is for local variables. Anything put on it by a function will be removed when the function returns.



            While some implementations may put some global variables at the base of the stack, it certainly isn't a rule.






            share|improve this answer










            $endgroup$



            Those are global variables. Which generally are not allocated on either stack or heap. Exactly where they are is a longer discussion.



            Your heap space is for 'globally accessible' variables created during run time. Which is different to global variables, which are allocated before your main() function is entered. Heap space variables can be allocated, de-allocated, reallocated and resized. A global variable you're generally stuck with for the entire program execution.



            Your stack space is for local variables. Anything put on it by a function will be removed when the function returns.



            While some implementations may put some global variables at the base of the stack, it certainly isn't a rule.







            share|improve this answer













            share|improve this answer




            share|improve this answer










            answered Jun 6 at 13:13









            heketehekete

            1,1331 silver badge11 bronze badges




            1,1331 silver badge11 bronze badges
























                1
















                $begingroup$

                Consider:



                uint16_t _xValH[5000];
                uint16_t _xValL[5000];
                uint16_t _xVal[5000];
                //3*5000*2 bytes each = 30Kbytes

                int main(void) {


                These are global variable declarations. These declarations reserve permanent static space in RAM. The heap is for dynamic allocations in memory.






                share|improve this answer












                $endgroup$



















                  1
















                  $begingroup$

                  Consider:



                  uint16_t _xValH[5000];
                  uint16_t _xValL[5000];
                  uint16_t _xVal[5000];
                  //3*5000*2 bytes each = 30Kbytes

                  int main(void) {


                  These are global variable declarations. These declarations reserve permanent static space in RAM. The heap is for dynamic allocations in memory.






                  share|improve this answer












                  $endgroup$

















                    1














                    1










                    1







                    $begingroup$

                    Consider:



                    uint16_t _xValH[5000];
                    uint16_t _xValL[5000];
                    uint16_t _xVal[5000];
                    //3*5000*2 bytes each = 30Kbytes

                    int main(void) {


                    These are global variable declarations. These declarations reserve permanent static space in RAM. The heap is for dynamic allocations in memory.






                    share|improve this answer












                    $endgroup$



                    Consider:



                    uint16_t _xValH[5000];
                    uint16_t _xValL[5000];
                    uint16_t _xVal[5000];
                    //3*5000*2 bytes each = 30Kbytes

                    int main(void) {


                    These are global variable declarations. These declarations reserve permanent static space in RAM. The heap is for dynamic allocations in memory.







                    share|improve this answer















                    share|improve this answer




                    share|improve this answer








                    edited Jun 7 at 10:07









                    Peter Mortensen

                    1,5743 gold badges14 silver badges22 bronze badges




                    1,5743 gold badges14 silver badges22 bronze badges










                    answered Jun 6 at 23:41









                    Josko MarsicJosko Marsic

                    112 bronze badges




                    112 bronze badges
























                        0
















                        $begingroup$

                        The Standard does not require freestanding implementations to provide any sort of heap. In some cases, they will pre-allocate a certain amount of space for use by the malloc() family of functions, with such space being essentially wasted if no such functions are ever used. In other cases, the compiler will reserve a certain amount of RAM for the stack and then make available to malloc() all storage that isn't and won't be used for any other purpose. In still other cases, an implementation won't provide malloc() but will provide the starting and ending address of a range of storage that the implementation has been told the hardware has, but which the implementation itself has no use for; a user application may then subdivide this range of addresses via whatever means it sees fit.



                        In many cases, the latter approach is the best, because user-written allocation functions can offer finer control over allocations and fallback logic than malloc(). For example, it may be useful to determine, before performing a bunch of allocations, whether all can be guaranteed to succeed (eliminating the need to gracefully recover from an allocation failure in the middle of a task). While malloc() provides no such flexibility, user-written allocation functions can.






                        share|improve this answer










                        $endgroup$














                        • $begingroup$
                          "The Standard" can refer to a very large number of documents. Please say which standard you are referring.
                          $endgroup$
                          – Stig Hemmer
                          Jun 7 at 7:38










                        • $begingroup$
                          The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
                          $endgroup$
                          – supercat
                          Jun 7 at 15:18
















                        0
















                        $begingroup$

                        The Standard does not require freestanding implementations to provide any sort of heap. In some cases, they will pre-allocate a certain amount of space for use by the malloc() family of functions, with such space being essentially wasted if no such functions are ever used. In other cases, the compiler will reserve a certain amount of RAM for the stack and then make available to malloc() all storage that isn't and won't be used for any other purpose. In still other cases, an implementation won't provide malloc() but will provide the starting and ending address of a range of storage that the implementation has been told the hardware has, but which the implementation itself has no use for; a user application may then subdivide this range of addresses via whatever means it sees fit.



                        In many cases, the latter approach is the best, because user-written allocation functions can offer finer control over allocations and fallback logic than malloc(). For example, it may be useful to determine, before performing a bunch of allocations, whether all can be guaranteed to succeed (eliminating the need to gracefully recover from an allocation failure in the middle of a task). While malloc() provides no such flexibility, user-written allocation functions can.






                        share|improve this answer










                        $endgroup$














                        • $begingroup$
                          "The Standard" can refer to a very large number of documents. Please say which standard you are referring.
                          $endgroup$
                          – Stig Hemmer
                          Jun 7 at 7:38










                        • $begingroup$
                          The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
                          $endgroup$
                          – supercat
                          Jun 7 at 15:18














                        0














                        0










                        0







                        $begingroup$

                        The Standard does not require freestanding implementations to provide any sort of heap. In some cases, they will pre-allocate a certain amount of space for use by the malloc() family of functions, with such space being essentially wasted if no such functions are ever used. In other cases, the compiler will reserve a certain amount of RAM for the stack and then make available to malloc() all storage that isn't and won't be used for any other purpose. In still other cases, an implementation won't provide malloc() but will provide the starting and ending address of a range of storage that the implementation has been told the hardware has, but which the implementation itself has no use for; a user application may then subdivide this range of addresses via whatever means it sees fit.



                        In many cases, the latter approach is the best, because user-written allocation functions can offer finer control over allocations and fallback logic than malloc(). For example, it may be useful to determine, before performing a bunch of allocations, whether all can be guaranteed to succeed (eliminating the need to gracefully recover from an allocation failure in the middle of a task). While malloc() provides no such flexibility, user-written allocation functions can.






                        share|improve this answer










                        $endgroup$



                        The Standard does not require freestanding implementations to provide any sort of heap. In some cases, they will pre-allocate a certain amount of space for use by the malloc() family of functions, with such space being essentially wasted if no such functions are ever used. In other cases, the compiler will reserve a certain amount of RAM for the stack and then make available to malloc() all storage that isn't and won't be used for any other purpose. In still other cases, an implementation won't provide malloc() but will provide the starting and ending address of a range of storage that the implementation has been told the hardware has, but which the implementation itself has no use for; a user application may then subdivide this range of addresses via whatever means it sees fit.



                        In many cases, the latter approach is the best, because user-written allocation functions can offer finer control over allocations and fallback logic than malloc(). For example, it may be useful to determine, before performing a bunch of allocations, whether all can be guaranteed to succeed (eliminating the need to gracefully recover from an allocation failure in the middle of a task). While malloc() provides no such flexibility, user-written allocation functions can.







                        share|improve this answer













                        share|improve this answer




                        share|improve this answer










                        answered Jun 6 at 19:27









                        supercatsupercat

                        39.2k1 gold badge66 silver badges115 bronze badges




                        39.2k1 gold badge66 silver badges115 bronze badges














                        • $begingroup$
                          "The Standard" can refer to a very large number of documents. Please say which standard you are referring.
                          $endgroup$
                          – Stig Hemmer
                          Jun 7 at 7:38










                        • $begingroup$
                          The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
                          $endgroup$
                          – supercat
                          Jun 7 at 15:18

















                        • $begingroup$
                          "The Standard" can refer to a very large number of documents. Please say which standard you are referring.
                          $endgroup$
                          – Stig Hemmer
                          Jun 7 at 7:38










                        • $begingroup$
                          The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
                          $endgroup$
                          – supercat
                          Jun 7 at 15:18
















                        $begingroup$
                        "The Standard" can refer to a very large number of documents. Please say which standard you are referring.
                        $endgroup$
                        – Stig Hemmer
                        Jun 7 at 7:38




                        $begingroup$
                        "The Standard" can refer to a very large number of documents. Please say which standard you are referring.
                        $endgroup$
                        – Stig Hemmer
                        Jun 7 at 7:38












                        $begingroup$
                        The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
                        $endgroup$
                        – supercat
                        Jun 7 at 15:18





                        $begingroup$
                        The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
                        $endgroup$
                        – supercat
                        Jun 7 at 15:18












                        0
















                        $begingroup$

                        I hope this should clear things up. It examples the different method of memory allocation in standard C.



                        #include <stdint.h>
                        #include <stdlib.h>
                        #include <stm32f30x.h>

                        uint32_t static_allocation;

                        int main(void)
                        uint32_t stack_allocation;
                        static uint32_t private_static_allocation;
                        uint32_t *heap_allocation;

                        heap_allocation = malloc(4);

                        static_allocation = 0x11111111;
                        stack_allocation = 0x22222222;
                        private_static_allocation = 0x33333333;
                        *heap_allocation = 0x44444444;

                        while(1)
                        // Stop simulation here
                        __BKPT(0);
                        // remove not referenced warnings
                        (void)static_allocation;
                        (void)stack_allocation;
                        (void)private_static_allocation;
                        (void)heap_allocation;


                        free(heap_allocation);



                        A quick glimpse at symbol table the ARM Linker generously created shows:



                        private_static_allocation 0x20000004 Data 4 main.o(.data)
                        static_allocation 0x20000000 Data 4 main.o(.data)


                        Which means the linker knows, at compile time, where these variables will live.

                        Including the following objects in memory map:



                        0x20000010 0x00000200 Zero RW 2 HEAP startup_stm32f30x.o
                        0x20000210 0x00000400 Zero RW 1 STACK startup_stm32f30x.o


                        And to check it really works like this, simulation debugger shows:



                        enter image description here



                        Notice stack_allocation isn't on the actual stack yet, but in a register. This is due to the small amount of variables in this example. Even with -O0 the compiler optimizes stack variables.



                        Also notice the place of 0x11.., 0x22.. with 0x44.. being inside the heap object.

                        But no other objects are in here. This means that you can safely reduce heap to 0 if you do not use malloc. Some library functions do implicitly.



                        Both heap and stack overflow are not warned about during compilation since they are runtime errors.




                        Relevant documentations: __use_no_heap.






                        share|improve this answer












                        $endgroup$



















                          0
















                          $begingroup$

                          I hope this should clear things up. It examples the different method of memory allocation in standard C.



                          #include <stdint.h>
                          #include <stdlib.h>
                          #include <stm32f30x.h>

                          uint32_t static_allocation;

                          int main(void)
                          uint32_t stack_allocation;
                          static uint32_t private_static_allocation;
                          uint32_t *heap_allocation;

                          heap_allocation = malloc(4);

                          static_allocation = 0x11111111;
                          stack_allocation = 0x22222222;
                          private_static_allocation = 0x33333333;
                          *heap_allocation = 0x44444444;

                          while(1)
                          // Stop simulation here
                          __BKPT(0);
                          // remove not referenced warnings
                          (void)static_allocation;
                          (void)stack_allocation;
                          (void)private_static_allocation;
                          (void)heap_allocation;


                          free(heap_allocation);



                          A quick glimpse at symbol table the ARM Linker generously created shows:



                          private_static_allocation 0x20000004 Data 4 main.o(.data)
                          static_allocation 0x20000000 Data 4 main.o(.data)


                          Which means the linker knows, at compile time, where these variables will live.

                          Including the following objects in memory map:



                          0x20000010 0x00000200 Zero RW 2 HEAP startup_stm32f30x.o
                          0x20000210 0x00000400 Zero RW 1 STACK startup_stm32f30x.o


                          And to check it really works like this, simulation debugger shows:



                          enter image description here



                          Notice stack_allocation isn't on the actual stack yet, but in a register. This is due to the small amount of variables in this example. Even with -O0 the compiler optimizes stack variables.



                          Also notice the place of 0x11.., 0x22.. with 0x44.. being inside the heap object.

                          But no other objects are in here. This means that you can safely reduce heap to 0 if you do not use malloc. Some library functions do implicitly.



                          Both heap and stack overflow are not warned about during compilation since they are runtime errors.




                          Relevant documentations: __use_no_heap.






                          share|improve this answer












                          $endgroup$

















                            0














                            0










                            0







                            $begingroup$

                            I hope this should clear things up. It examples the different method of memory allocation in standard C.



                            #include <stdint.h>
                            #include <stdlib.h>
                            #include <stm32f30x.h>

                            uint32_t static_allocation;

                            int main(void)
                            uint32_t stack_allocation;
                            static uint32_t private_static_allocation;
                            uint32_t *heap_allocation;

                            heap_allocation = malloc(4);

                            static_allocation = 0x11111111;
                            stack_allocation = 0x22222222;
                            private_static_allocation = 0x33333333;
                            *heap_allocation = 0x44444444;

                            while(1)
                            // Stop simulation here
                            __BKPT(0);
                            // remove not referenced warnings
                            (void)static_allocation;
                            (void)stack_allocation;
                            (void)private_static_allocation;
                            (void)heap_allocation;


                            free(heap_allocation);



                            A quick glimpse at symbol table the ARM Linker generously created shows:



                            private_static_allocation 0x20000004 Data 4 main.o(.data)
                            static_allocation 0x20000000 Data 4 main.o(.data)


                            Which means the linker knows, at compile time, where these variables will live.

                            Including the following objects in memory map:



                            0x20000010 0x00000200 Zero RW 2 HEAP startup_stm32f30x.o
                            0x20000210 0x00000400 Zero RW 1 STACK startup_stm32f30x.o


                            And to check it really works like this, simulation debugger shows:



                            enter image description here



                            Notice stack_allocation isn't on the actual stack yet, but in a register. This is due to the small amount of variables in this example. Even with -O0 the compiler optimizes stack variables.



                            Also notice the place of 0x11.., 0x22.. with 0x44.. being inside the heap object.

                            But no other objects are in here. This means that you can safely reduce heap to 0 if you do not use malloc. Some library functions do implicitly.



                            Both heap and stack overflow are not warned about during compilation since they are runtime errors.




                            Relevant documentations: __use_no_heap.






                            share|improve this answer












                            $endgroup$



                            I hope this should clear things up. It examples the different method of memory allocation in standard C.



                            #include <stdint.h>
                            #include <stdlib.h>
                            #include <stm32f30x.h>

                            uint32_t static_allocation;

                            int main(void)
                            uint32_t stack_allocation;
                            static uint32_t private_static_allocation;
                            uint32_t *heap_allocation;

                            heap_allocation = malloc(4);

                            static_allocation = 0x11111111;
                            stack_allocation = 0x22222222;
                            private_static_allocation = 0x33333333;
                            *heap_allocation = 0x44444444;

                            while(1)
                            // Stop simulation here
                            __BKPT(0);
                            // remove not referenced warnings
                            (void)static_allocation;
                            (void)stack_allocation;
                            (void)private_static_allocation;
                            (void)heap_allocation;


                            free(heap_allocation);



                            A quick glimpse at symbol table the ARM Linker generously created shows:



                            private_static_allocation 0x20000004 Data 4 main.o(.data)
                            static_allocation 0x20000000 Data 4 main.o(.data)


                            Which means the linker knows, at compile time, where these variables will live.

                            Including the following objects in memory map:



                            0x20000010 0x00000200 Zero RW 2 HEAP startup_stm32f30x.o
                            0x20000210 0x00000400 Zero RW 1 STACK startup_stm32f30x.o


                            And to check it really works like this, simulation debugger shows:



                            enter image description here



                            Notice stack_allocation isn't on the actual stack yet, but in a register. This is due to the small amount of variables in this example. Even with -O0 the compiler optimizes stack variables.



                            Also notice the place of 0x11.., 0x22.. with 0x44.. being inside the heap object.

                            But no other objects are in here. This means that you can safely reduce heap to 0 if you do not use malloc. Some library functions do implicitly.



                            Both heap and stack overflow are not warned about during compilation since they are runtime errors.




                            Relevant documentations: __use_no_heap.







                            share|improve this answer















                            share|improve this answer




                            share|improve this answer








                            edited Jun 7 at 12:16

























                            answered Jun 7 at 12:10









                            Jeroen3Jeroen3

                            14.3k20 silver badges54 bronze badges




                            14.3k20 silver badges54 bronze badges































                                draft saved

                                draft discarded















































                                Thanks for contributing an answer to Electrical Engineering Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid


                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.

                                Use MathJax to format equations. MathJax reference.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f442239%2fheap-allocation-on-a-microcontroller%23new-answer', 'question_page');

                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown









                                Popular posts from this blog

                                Tamil (spriik) Luke uk diar | Nawigatjuun

                                Align equal signs while including text over equalitiesAMS align: left aligned text/math plus multicolumn alignmentMultiple alignmentsAligning equations in multiple placesNumbering and aligning an equation with multiple columnsHow to align one equation with another multline equationUsing \ in environments inside the begintabularxNumber equations and preserving alignment of equal signsHow can I align equations to the left and to the right?Double equation alignment problem within align enviromentAligned within align: Why are they right-aligned?

                                Training a classifier when some of the features are unknownWhy does Gradient Boosting regression predict negative values when there are no negative y-values in my training set?How to improve an existing (trained) classifier?What is effect when I set up some self defined predisctor variables?Why Matlab neural network classification returns decimal values on prediction dataset?Fitting and transforming text data in training, testing, and validation setsHow to quantify the performance of the classifier (multi-class SVM) using the test data?How do I control for some patients providing multiple samples in my training data?Training and Test setTraining a convolutional neural network for image denoising in MatlabShouldn't an autoencoder with #(neurons in hidden layer) = #(neurons in input layer) be “perfect”?