Page 2 of 2

Re: Confusion with calculation of ram usage

Posted: Mon Mar 10, 2014 9:09 am
by dciliske
Just to clarify about your "last byte" example. When you add the second variable, which pushes you over the RAM limit, you're going to fail the static compilation. compcode will yell at you and tell you that you are over memory limits; go ahead and try to allocate a 256 MB global array and see what it says.

I agree that rsg appears to have answered your question fairly correctly, though one thing I'll comment just to make you aware: when you allocate a variable in a function, this allocation happens within the stack of the current task, in the current stack frame. I realize what I'm about to say is getting a little tangential, but feel I should add some further information.

For primitives (aka, non-(C++)objects) allocation itself does not do anything; all it does is affect what offset the output assembly uses to access the "variable". This means that your original example

Code: Select all

char buff[1024]; 

void MyFunction(void)
{
    char buffer[4096];

    buffer[0] = 0;
}

void main(void)
{
    MyFunction();
} 
will compile and run just fine. Until someone tries to use a byte beyond 'buffer[1023]'. While you declared a 4096 byte array, this declaration did not 'allocate' any memory; it is simply stuck in the local stack frame in the 1024 byte stack. When someone goes to use a byte beyond 'buffer[1023]', you've got a stack overflow and now they're writing to someone else's memory. The compiler has no way of knowing that you will use this function in that manner and thus cannot see that this will blow up. (If you wonder why it can't determine this, refer to The Halting Problem; it's uncomputable).

Re: Confusion with calculation of ram usage

Posted: Mon Mar 10, 2014 9:43 am
by seulater
For primitives (aka, non-(C++)objects) allocation itself does not do anything; all it does is affect what offset the output assembly uses to access the "variable".
This is one of the things where i am confused. I might as well have replaced char buffer[4096]; with char *buffer, as it seems its doing the same thing, or am i wrong still.

I am having a hell of a time getting my thoughts properly in text. I made this drawing to help with my confusion.
2014-03-10_12-01-39.jpg
2014-03-10_12-01-39.jpg (159.09 KiB) Viewed 3114 times
From what everyone is saying is that when i declare buffer[4096] it basically creates a pointer to where that data starts at.
yet it keeps no knowledge of how long that data should be even though i said it was an array of 4096 bytes. So how then would it know where to put another new variable buf[128]? without overwriting the area for the first one.

Re: Confusion with calculation of ram usage

Posted: Mon Mar 10, 2014 8:02 pm
by Ridgeglider
When you write the following code within a function:
Buffer[4096];
Buf[128];
you are defining arrays without an explicit initialization, with no linkage, and as two variables w/ automatic storage duration. Objects with automatic storage have an undetermined initial value unless they include an initializer. This means that although space for the array gets allocated out of the task's stack, (first Buffer, then Buf, just as you drew) no data is written to either array yet. Data only gets written into individual elements of an array by explicit calls from within the function. Because space is allocated, (even though not written) the address of Buf is correct with respect to Bufffer. Now, lets say Buf exceeds the task's stack space by one byte. Merely defining Buf causes no issue. However, if you try to store data in Buf's last byte, the stack would overflow and which MIGHT cause an issue by overwriting either an adjoining task's stack space, the ISR RAM, or a heap-allocated buffer. I don't think compcode will catch automatic variables defined inside a function...

When you write the same code outside a function, the array has static storage duration and it's implicitly initialized with the default value of 0. Because these vars are not part of a function that runs as a task, I don't think they're allocated from a particular stack's space, but from the heap. I think compcode will catch these definitions if they exceed the RAM allocated for heap: ".bss will not fit in region ram" or "region ram overflowed by xxx bytes"

Re: Confusion with calculation of ram usage

Posted: Tue Mar 11, 2014 4:45 am
by rsg
Ridgeglider wrote:from the heap
Nope, not from the heap; static allocation does come from .bss, but that is not the heap.