This is similar to: Is this function subject to memory fragmentation?
I am trying to get my head around Memory fragmentation in Arduino's and embedded systems in general.
Currently I have a function in a __lcdAux__
Class which is responsible for doing basic operation on the lcd.
One of the members of the class is a char array double2StrBuff1
which is used with __dtostrf()__
to create a double which is then passed to sprintf
. So the following function (__lcdAux::UpdatePosition__
) is responsible for updating the position on the lcd.
void lcdAux::UpdatePosition(double MtXPosLengthUnits) {
lcd->setCursor(0, 2);
dtostrf(MtXPosLengthUnits, 0,3, double2StrBuff1);
sprintf(lcdBuff, "X: %s", double2StrBuff1);
lcd->print(lcdBuff);
}
Currently, I am under the impression that by defining once the class as a global variable and then using it throughout the program, then the char array is allocated only once memory space. Therefore by using it afterwards no memory fragmentation occurs.
However, I read that functions allocate space on the stack which is immediately recoved when the function is exited. Therefore I am curious if the following declaration is any different in terms of memory fragmentation.
void lcdAux::UpdatePosition(double MtXPosLengthUnits) {
lcd->setCursor(0, 2);
char double2StrBuff1[10];
dtostrf(MtXPosLengthUnits, 0,3, double2StrBuff1);
sprintf(lcdBuff, "X: %s", double2StrBuff1);
lcd->print(lcdBuff);
}
To sum up:
- by putting the declaration for variable
__char double2StrBuff1[10];__
inside the function, is the memory allocated from the stack and therefore recovered upon exiting the function (therefore there is no need to declarate a member variable on the class level),
OR
- is the fact that
__double2StrBuff1__
is a pointer means that the pointer is allocated in the stack but the values are located in the heap (therefore what I am doing makes sense)?
PS: Because some might point out that __"X: %s"__
is worse in terms of memory usage and fragmentation, I'll state the following. Instead of the format string __"X:%s"__
I use a _PROGMEM
const char_ array
and __strcpy_P()_
, but to simplify the question I replaced it with the literal string , since I feel that is another problem.
-
The term memory fragmentation refers to heap fragmentation (when using malloc/free or new/delete). en.wikipedia.org/wiki/Memory_managementMikael Patel– Mikael Patel2016年08月26日 15:43:25 +00:00Commented Aug 26, 2016 at 15:43
2 Answers 2
by putting the declaration for variable char double2StrBuff1[10]; inside the function, is the memory allocated from the stack and therefore recovered upon exiting the function
This is correct.
is the fact that double2StrBuff1 is a pointer means that the pointer is allocated in the stack but the values are located in the heap (therefore what I am doing makes sense)?
No, double2StrBuff1
is not a pointer, it's an array. In C and C++,
when you use an array identifier, it decays to a pointer in many
situations. However, for the purpose of memory allocation, an array is
very different from a pointer.
Heap allocation only happens when using malloc()
and new
.
-
Could you point me to some reading material which will improve my understanding of how array identifiers are different to pointers?NMech– NMech2016年08月29日 08:47:57 +00:00Commented Aug 29, 2016 at 8:47
-
@NMech: Take a look at this question (and its answers, and maybe the linked references) on Stack Overflow: What is array decaying?.Edgar Bonet– Edgar Bonet2016年08月29日 09:37:57 +00:00Commented Aug 29, 2016 at 9:37
The examples in the question above use 1) global and 2) local aka stack allocation and do not give heap fragmentation. The heap is not involved.
Below is a version that may give heap fragmentation (though a very low risk):
void lcdAux::UpdatePosition(double MtXPosLengthUnits) {
lcd->setCursor(0, 2);
char* double2StrBuff1 = (char*) malloc(10);
dtostrf(MtXPosLengthUnits, 0,3, double2StrBuff1);
sprintf(lcdBuff, "X: %s", double2StrBuff1);
lcd->print(lcdBuff);
free(double2StrBuff1);
}
Please not that heap allocation is very slow compared to stack allocation.
C/C++ does not have any implicit heap allocations (in the language). A local array in a function is allocated on the stack and removed when the function returns. The only library functions that can generate stack fragmentation are setjmp and longjmp if used to create a spaghetti stack.