Hexadecimal to string without C++ standard library functions For the purposes of this code review, I will use the standard library, but pretend that &lt;cstddef&gt; is &lt;stddef.h&gt;, that I didn't use std::cout, that new and delete[] are overloaded and call custom malloc functions, etc. So this is -std=c++11 -ffreestanding.

Here are my questions:


Currently my tohex function returns a buffer allocated on the heap. Is it better if I have the caller pass the buffer as a parameter instead? Is there a way to avoid heap allocation without using variable length arrays?
I have a separate function that counts the size of the digits so that I can reverse the string. What's an alternate way of doing this?
Should I prefer uint8_t or int or is unsigned okay? I don't think there should be any issues with what type I choose in the code shown.




#include &lt;cstddef&gt;

unsigned count(unsigned n)
{
    int digits = 0;
    while (n &gt; 0)
    {
        ++digits;
        n /= 16;
    }
    return digits;
}

char* tohex(unsigned n)
{
    unsigned size = count(n) + 1;
    char *buffer = new char[size];
    unsigned index = size - 2;
    while (n &gt; 0)
    {
        unsigned mod = n % 16;

        if (mod &gt;= 10)
            buffer[index--] = (mod - 10) + 'A';
        else
            buffer[index--] = mod + '0';

        n /= 16;
    }
    buffer[size - 1] = '\0';
    return buffer;
}

#include &lt;iostream&gt;

int main()
{
    char *buffer = tohex(0xBEEFCAFE);
    std::cout &lt;&lt; buffer;
    delete[] buffer;
    return 0;
}
As both the others have said use std::string if you are going to dynamically allocate space. Its not going to be worse than your code;if your compiler implements the small string optimizations its actually goinf to do better than your code as no dynamic memory will be used.

unsigned count(unsigned n)


Well we know that unsigned have a particular size sizeof(unsigned). So we know that the max size of the array is sizeof(unsigned)*CHAR_BITS/4. On most systems this will be 8 on some it will be 16. But neither of these numbers is huge why not always use the maximum size (it will save you the time of calculating an exact size.

You can also get away with no dynamic memory allocation by having a static array in the function (not thread safe but it does not look like that is your issue).

Others have suggested replacing the n /= 16; by n &gt;&gt; 4;. DON'T do that (unless you think it expresses intent better). It hides the intent of the code. The code is supposed to express the intent in the most natural way possible. It is the job of the compiler to see that this can be optimized to a shift by 4 and I am dead sure the compiler will generate the most efficient code.