Search code examples
craspberry-piraspberry-pi-pico

trying to concat two pointer char but one of them is changing


I am using Raspberry Pi pico with C. I am trying to take 2 different decimal value to char then concat them. I am taking those decimal values from rfid. The values ​​coming from rfid are not decimal at first, I convert these values ​​to decimal by processing.

char *a;
char *b;
a = lltoa(decimal_2, 10);
printf(a);
b = lltoa(decimal, 10);
printf(b);
int newSize = strlen(a) + strlen(b) + 1;
char *newBuffer = (char *)malloc(newSize);
printf("\n");
strcpy(newBuffer, a);
strcat(newBuffer, b);
printf(newBuffer);

The output is :

999210803000150
150210803000150

The 999 which is a's value is changing. Why char *a is changing ?

Here is my lltoa function (I took from stack overflow):


char *lltoa(long long val, int base)
{

    static char buf[64] = {0};

    int i = 62;
    int sign = (val < 0);
    if (sign)
        val = -val;

    if (val == 0)
        return "0";

    for (; val && i; --i, val /= base)
    {
        buf[i] = "0123456789abcdef"[val % base];
    }

    if (sign)
    {
        buf[i--] = '-';
    }
    return &buf[i + 1];
}

Solution

  • Inside the lltoa function you have:

    static char buf[64] = {0};
    

    When you define a local variable as static it means there's only one single instance of the variable, shared between all calls to the function.

    So when you call lltoa(decimal_2, 10) the contents of buf is set up one way. Then in the second call lltoa(decimal, 10) you overwrite the contents of buf.

    And since you only have a single buf, both the pointers a and b will both point to this one single buf.

    Since you want to be able to handle different bases you can't use the standard snprintf as I would otherwise suggest, so my recommendation is that you pass a pointer to a large enough buffer as an argument:

    char *lltoa(long long val, int base, char *buf, size_t buflen);