Strange behavior

Hello guys!

I have this piece of code below

void Core::sendAT( const __FlashStringHelper *_command, const __FlashStringHelper *_response )
{
    bool completed = true;
    
    start:
    char *command  = static_cast<char*>( malloc( sizeof *command * sizeof _command ) );
    char *response = static_cast<char*>( malloc( sizeof *response * sizeof _response ) );

    byte cursor = 0;
    while ( ( command[cursor] = pgm_read_byte_near( ( char* ) _command + cursor ) ) != nul )
        cursor++;
    
    cursor = 0;    
    while ( ( response[cursor] = pgm_read_byte_near( ( char* ) _response + cursor ) ) != nul )
        cursor++;

    debug << F( "Command: " ) << command << crlf;
    debug << F( "Response: " ) << response << crlf;
    
    free( command );
    free( response );
}

I’m passing F() macro strings to both parameters ( F( “AT+RESTORE” ), F( “ready” ) ).
Both parameters are giving its sizeof as 2.

What I am not expecting is that when the code goes through the first while and I put the debug command BEFORE the second while, the program prints the whole string.

When its located as the code above, I am getting garbage on first print and the correct value for the second parameter.

If I set the malloc size manually, it’s all good. Both values are printed correctly.

Why am I getting this behavior?

Thanks in advance!

sizeof _command gives you the size of a pointer into memory, so 2 bytes sizeof *command is the size of a char, so 1 byte

and 2 * 1 = 2, so all feels logic :)

strlen(_command) is probably what you want (and probably you need one extra char for the \0 in your malloc if you want proper C strings and be able to print them out)

Thanks a lot for the insight J-M-L. I was mixing up some concepts.

But though, what wonders me the most is even if its allocating 2 bytes only, when I ran just one while, it printed a size 40 string. It doesn't make sense.

In addition, since I'm using __FlashStringHelper I don't have proper/auxiliar methods to calculate its length without a cast.

Is there a strlen_P version?

Breno999: But though, what wonders me the most is even if its allocating 2 bytes only, when I ran just one while, it printed a size 40 string. It doesn't make sense.

Well you are corrupting the memory by writing beyond what malloc gave you. If you are lucky and nothing else is in there but zeros and that's why your string is correctly terminated and you can be fine but that's definitely bogus code :)

Delta_G: Is there a strlen_P version?

Yes - indeed what I should have said

Cf http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

Those P methods need const char* variables to be used.

I know I could just cast tem into it, but since I went the distance to use the __FlashStringHelper I was searching for a code pointed to that way.

Just want to learn a bit more, because it's been almost 20 years that I wasn't even thinking about C++...

Yet again, thanks for the additional explanation J-M-L.

Now it all makes sense.

You start to get lazy while programming higher level languages, lol.