void setup()
{
Serial.begin(19200);
}
void loop()
{
delay(3000);
char *p = (char *)malloc(sizeof(char) * 1); //Allocate some memory.
for(int i(0); i < 5; i++)
{
Serial.print("Begin len is ");
Serial.println(strlen(p));
realloc(p,(sizeof(char) * (strlen(p)+1))); //Increase size of allocated memory by 1 byte.
char c[1];
c[0] = (char) 56;
strcat(p, c); //Append 1 char.
Serial.print("End len is ");
Serial.println(strlen(p));
}
Serial.println(p); //Print the result.
free(p);
while(true);
}
When I open my serial console, after 3s delay I can see this
Begin len is 0
End len is 3
Begin len is 3
End len is 6
Begin len is 6
End len is 9
Begin len is 9
End len is 12
Begin len is 12
End len is 15
8ÿ 8ÿ 8ÿ 8ÿ 8ÿ
Why does Arduino allocate additional 2 bytes of memory? What are these strange symbols in output?
This is nuts if you are trying to use strcat as there is no null termination, so it is not a string.
Try this instead:
char c[2] = {0};
c[0] = '8'; //and you might as well use an ascii character rather than its code
As there was no null termination, I can only assume that there is a random 0 in the ram around 2 bytes on from your '8'. As such strlen keeps reading until it sees that.
strlen does not return the size of an array, just the size of its contents up to the first null character.
The strange symbols will be the result of a stack overflow due to strcat working with your non null-terminated string.
Given that it's a constant, you could equally have used "8" which will compile to an array of two characters containing the character '8' followed by a null terminator.
This basic approach is not a very good approach to use with an Arduino. On versions up to 1.0.4 you may encounter memory corruption caused by a bug in free(), and in all versions you're vulnerable to heap fragmentation. Using dynamic memory to hold dynamic data is not a good idea on a platform with so little memory and such limited capability to manage that memory.
CagoBHuK:
I should use String class instead of manpulating memory on my own.
I wouldn't recommend it. That still uses dynamic memory to hold your data, which is simply not a sensible approach on a platform with such limited heap space and such limited capability to manage it.
Far better IMO to allocate a static buffer big enough to hold the longest string you need to deal with, and then ensure that you handle the 'overflow' case sensibly.