Strange things with dynamic memory allocation and strcat

Hello there. I got this code:

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?

  char *p = (char *)malloc(sizeof(char) * 1); //Allocate some memory.

only allocates 1 byte! Why are you multiplying by 1?

Mark

    char c[1];
    c[0] = (char) 56;

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.

Thanks for your reply. Changed the code.

    char c[2];
    c[0] = '8';
    c[1] = '\0';

This worked fine for me.

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.

Thanks for your replies. Now I imagine, how it works. I should use String class instead of manpulating memory on my own.
Sorry for my bad english. :slight_smile:

Please note that in versions of the IDE up to and including 1.0.3, the String library has bugs as discussed here and here.

In particular, the dynamic memory allocation used by the String class may fail and cause random crashes.

I recommend reworking your code to manage without String. Use C-style strings instead (strcpy, strcat, strcmp, etc.), as described here for example.

Alternatively, install the fix described here: Fixing String Crashes

Preferably upgrade your IDE to version 1.0.4 or above at: http://arduino.cc/en/Main/Software

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.