Send Char* to Serial

Hi All

I expect to get an result like “012345678”, but “ááááááááááááááááááááááááááááááá«” is what I got
Can someone please point out the mistake in my code?? Thanks

void setup()
{
  Serial.begin(9600);
  char readBuf[10] = {'0','1','2','3','4','5','6','7','8'};
  char* myStr;
  for( int i=0; i <= 10; i++){
      strcat( myStr, readBuf[i] );
    }
  Serial.println(myStr);
}

void loop()
{ 
}

void strcat(char* original, char appended)
{
  while (*original++)
    ;
  *original++ = appended;
  if (appended)
    *original = '\0';
}

char* myStr; // this does not allocate any storage for your string! Try:

char myStr[10];

There's already a strcat() method, too. No need to re-invent the wheel.

A couple of comments:

  • You’ve declared myStr to be a pointer to char, but haven’t told it where to point (it could be pointing anywhere, including at the CPU’s register space!). It might be better to declare it to be an array of char large enough to contain whatever you want to put into it.
  • In the C world, function names beginning with “str” are reserved for compiler/library use. I don’t know if C++ has that restriction, but I’d suggest not looking for trouble. How about “addchar()” or “charcat()”?
  • A habit that will serve you well would be to define functions (or locate a function prototype statement) above where they’re first called.

In the C world, function names beginning with “str” are reserved for compiler/library use.

Only by convention; there is no language restriction to using “str” as a prefix.
There is no reservation.

well… this is what’s happenning here…

LibC string functions (which sit underneath Arduino) assume your strings are null terminated - ie. the what’s stored in the char array is “ABCD\x0” and it’s interpreted as the string “ABCD”.

Note the standard strcat parameter refs (tip: google for strcat)
destination: Pointer to the destination array, which should contain a C string, and be large enough to contain the concatenated resulting string.
source: C string to be appended. This should not overlap destination.

Now - you properly allocated space for your buf…

char readBuf[10] = {'0','1','2','3','4','5','6','7','8'};

but then you did this…

  char* myStr;
  for( int i=0; i <= 10; i++){
      strcat( myStr, readBuf[i] );
    }

First of all - when you do char* myStr , you’re not allocating memory, you’re only declaring the variable. This could be pointing to anywhere at all in SRAM. Then when you’re passing this to strcat, strcat dutifully looks for the null ‘\x0’ wherever in RAM that myStr happens to be pointing to understand where the string is ending (random luck)… and THEN adding your readbuf… this is essentially trashing the memory :slight_smile:

solution is to first declare myStr & allocate memory - SUFFICIENT memory to accommodate whatever you’re going to concatenate to it

char myStr[100];

The other gotcha is strcat takes null terminated string as the other parameter as well… your readBuf is NOT a null terminated string… so it will keep appending chars till it runs it runs accidentally into an ‘\x0’ somewhere in memory.

For the specific application you’re trying to work, it might be simpler to save the current string length within myStr in a int counter variable & use simple array access rather than use LibC string functions -

myStr[maxptr] = readBuf[i];
maxptr++;

@AWOL: ISO/IEC 9899 (the international C language standard document) says:

7.26 Future library directions
1 The following names are grouped under individual headers for convenience. All external names described below are reserved no matter what headers are included by the program.

7.26.10 General utilities <stdlib.h>
1 Function names that begin with str and a lowercase letter may be added to the declarations in the <stdlib.h> header.

7.26.11 String handling <string.h>
1 Function names that begin with str, mem, or wcs and a lowercase letter may be added to the declarations in the <string.h> header.

The key being the word "external"

Correct. The minimum requirement, then, is that the function be declared as "static" to restrict its scope to this translation unit.

The obvious danger in external linkage is that the OP's function might be called by library code which (rightfully) expects very different behavior.

My own opinion (and it's only opinion) is that it's good practice to avoid impinging on reserved namespaces altogether.

The other gotcha is strcat takes null terminated string as the other parameter as well... your readBuf is NOT a null terminated string... so it will keep appending chars till it runs it runs accidentally into an '\x0' somewhere in memory.

Actually I believe it IS null terminated since he allocated an array size of 10 but only initialized the first 9 members. I believe that the compiler would initialize the tenth to zero.

Agree it would have been better to specifically initialize the last member to 0.