Why are "\000" characters being inserted between characters of a char array?

Viewed 407

I am attempting to read an incoming stream of data from UART, and trying to add each character received to an array of char until characters \r and \n are received (in that order).

I have written a function (char read_uart()) to wait for then return when a single character is received. This function properly receives and returns the single character, as it should.

On top of this function, I have tried creating another which is supposed to read every character and add them to an array until the termination combination is received. This is it:

void read_full_uart(char *message[4096])
{
    char previousTwo[2] = {'\0', '\0'};
    for (uint16_t i = 0; !(previousTwo[0] == '\r' && previousTwo[1] == '\n'); i++)
    {
        char currentValue = read_uart();
        *(message + i) = currentValue;

        previousTwo[0] = previousTwo[1];
        previousTwo[1] = currentValue;
    }
}

and this is how I am calling it:

char message[4096];
read_full_uart(&message);

However, when transmitting "bitcoin" for example, this is what message turns out to be:

b\000\000\000i\000\000\000t\000\000\000c\000\000\000o\000\000\000i\000\000\000n\000\000\000\r\000\000\000\n\000\000\000

The characters are received intact, but have three \000 characters appended to them.

I am wondering why this is happening, and how it can be adjusted so that these additional characters are not being inserted.

1 Answers

There are two issues here.

First, what you're passing to the function isn't what it's expecting. &message has type char (*)[4096], i.e. a pointer to an array of size 4096 of char. The function meanwhile is expecting a char *[4096], i.e. an array of size 4096 of char *. This is a type mismatch.

The second is that on this line:

*(message + i) = currentValue;

Or equivalently:

message[i] = currentValue;

You're assigning a char to an array of type char *. This is also a type mismatch.

This issues should have been picked up by the compiler as warnings. If not, turn up the warning level by passing the options -Wall -Wextra (assuming gcc) and treat warnings as errors.

You can fix these errors by changing the function to take an array of char:

void read_full_uart(char message[4096])

Or equivalently:

void read_full_uart(char *message)

And by passing the array directly to the function:

read_full_uart(message);
Related