Serial.toCharArray Issue

I have come across an issue with the String.toCharArray() and String.getBytes functions.

It seems to drop the last character of the string, here is a test sketch I am using, am I doing something wrong or is this an issue?

void setup() { Serial.begin(9600);

String test_str = "ABCDEF";

int test_str_length = test_str.length(); char test_char_ary[test_str_length];

test_str.toCharArray(test_char_ary, test_str_length);

Serial.println(test_str); Serial.println(test_str_length); Serial.println(test_char_ary); }

void loop() { }

The output from this is

ABCDEF 6 ABCDE

So it seems that unless I have my syntax wrong the function is dropping the last character of the string.

I have come across an issue with the String.toCharArray() and String.getBytes functions.

So you titled your post "Serial.toCharArray issue". Why?

String test_str = "ABCDEF";

 int test_str_length = test_str.length();

So, test_str_length is 6.

char test_char_ary[test_str_length];

This array can now hold 5 characters and the terminating NULL.

Do you see where the "missing character" went missing?

char test_char_ary[test_str_length]; //<--------------[CONSTANT];with it should be a constant expression [7+1] etc
//I doubt arduino why this is not generating any error for above expression
//in c,c++ above expression is wrong

It is perfectly reasonable to allocate an array based on the value in a variable. It is necessary to make sure that the variable holds the correct value, though.

int test_str_length = test_str.length() + 1;

PaulS:

I have come across an issue with the String.toCharArray() and String.getBytes functions.

So you titled your post “Serial.toCharArray issue”. Why?

yeah, yeah, yeah… it was a typo! is it such a big deal?

Anyway, didn’t realise about the null termination, I had already +1 to the length to get around the problem and now thanks to your reply I understand why.

is it such a big deal?

Not really, but you can fix it. See how I did?

Need to simulate the things,

char x[i]; // how do  the compiler know the Value of i, because i is a variable

// so allocation must be on run time, // what will happen if i=4000 in run time, the how can we use or check x does not have the allocated memory

char x; // how do the compiler know the size of i, because i is a variable

I presume that this was meant to be char[ i ]. The size of i and the value in i are not the same thing. The compiler knows both. The value is the value at the time the array is (to be) defined. The resulting array size does not change as the value in the variable changes.

// so allocation must be on run time,

Yes.

// what will happen if i=4000 in run time, the how can we use or check x does not have the allocated memory

An excellent question. The allocation is guaranteed to succeed because dynamic allocation is performed. All that really happens is that the heap pointer is moved to beyond the "allocated" space. Whether the heap pointer is now valid, or not, is immaterial as far as the "allocation" is concerned.

In order for the Arduino to continue executing successfully, the heap pointer must remain valid at all times. But, there is no checking to ensure that it is. Hence, the unpredictable crashes that happen when the Arduino is out of memory.

Therefore, it is the programmer's responsibility to ensure that sufficient memory is available. That is, of course, not an easy task.

//Arduino failed allocate memory at runtime
// I was expecting that

void setup() {
 Serial.begin(9600);

 String test_str = "ABCDEF";

 int test_str_length =test_str.length();
 
 char test_char_ary[test_str_length+1]; // allocated the memory at run time what paulS said
 char dummyBuffer[10];
 unsigned int addr;
 test_str.toCharArray(test_char_ary, test_str_length);
 
 Serial.println(test_str);
 Serial.println(test_str_length);
 Serial.println(test_char_ary);
 
  addr=(unsigned int )test_char_ary;
  Serial.print("Addr test_char_ary:0x");
  Serial.println(addr,HEX); 
  
  addr=(unsigned int )dummyBuffer;
  Serial.print("dummyBuffer:0x");
  Serial.println(addr,HEX); 
       
}


void loop() {
  
  delay(1000);
}


--------------output------------------

ABCDEF
6
ABCDE
Addr test_char_ary:0x8D9
dummyBuffer:0x8E6
  1. local variable are in stack not heap area
  2. As I simulate the code run time memory are always in heap area.