why is free() adding weired character on a string pointer in c?

Viewed 54

I'm new to C language, less than two months old, but i have been experiencing a problem with malloc, realloc and free. I was writting a code to print numbers on stdout, and my method was, converting it to a string first and then printing it. Here is my code;(count is for keeping record of char printed.)

int print_num(int num, int count)
{
    int i = 0, len;
    char last, *ptr2, *ptr = (char *)malloc(sizeof(char));

    if (num == 0)
        return (print_char('0', count));
    if (num < 0)
        count = print_char('-', count);
    num = abs(num);
    while (num != 0)
    {
        last = (num % 10) + '0';
        if (i == 0)
            *(ptr) = last;
        else
        {
            ptr2 = (char *)realloc(ptr, i + 1);
            *(ptr2 + i) = last;
            ptr = ptr2;
        }
        num /= 10;
        i++;
    }
    len = strlen(ptr);
    for (i = len; i > 0; i--)
        count = print_char(ptr[i - 1], count);
    free(ptr);
    return (count);
}

The problem is that, the code works fine without free(ptr)or free(ptr2). When i call the function more than once in another function, i get weired char at the end of the string pointer ptr. Example when printing two numbers in a row

print_num(39, 0)
print_num(39, 0)

i get

Length:[39, U�39]

when i delete free(ptr), the code works fine, but their will be a memory leak. How can i make this work?

int print_char(char c, int count)
{
    write(1, &c, 1);
    return (count + 1);
}
1 Answers

You're using strlen on an array of bytes that isn't a string.

A string in C is a null terminated sequence of characters. You build up an array of characters in the memory pointed to by ptr, but don't add a terminating null byte. This by itself isn't a problem, but then you call strlen on it which expects a null terminated string. This results in the function reading past the end of allocated memory, triggering undefined behavior.

You already have the length of the array stored in i, so there's no need to call strlen. Just use that.

len = i;
Related