0

I am new to C++ and dynamic memory allocation.

I have this code to convert a number from decimal to hexadecimal, that uses a dynamic array:

int hexLen = value.length();
char* arrayPtr = new char[hexLen];

_itoa_s(stoi(dec), arrayPtr, 16);

string hexVal = static_cast<string>(arrayPtr);

delete[] charArrayptr;

When I used an array with a fixed size, _itoa_s() worked with it. However, when using a dynamic array, the compiler says that a method with the arguments given doesn't exist.

Is this something that I did wrong, or will _itoa_s() simply not work with a dynamic array?

Version with non-dynamic array (that works):

const int LENGTH = 20;
char hexCharArray[LENGTH];

_itoa_s(stoi(dec), hexCharArray, 16);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
MCSGaming
  • 3
  • 4
  • https://stackoverflow.com/questions/61160316/is-there-a-replacement-for-itoa-s-function-in-c – sweenish Dec 07 '21 at 18:23
  • The question is why do you want to use _itoa_s? There are easier ways to convert to hex while not having to use new/delete. – Pepijn Kramer Dec 07 '21 at 18:24
  • This might just be the MRE, but if the size is a constant in your code, you don't need a dynamic array at all. – sweenish Dec 07 '21 at 18:24

2 Answers2

0

This is how I would convert to hex to string (both pre C++20 and C++20)

#include <format> // C++20
#include <string>
#include <sstream>
#include <iostream>

int main()
{
    int value = 123;

    // pre c++20 formatting
    std::ostringstream os;
    os << "0x" << std::hex << value << "n";
    std::cout << os.str();

    // c++20 formatting
    auto string = std::format("0x{:x}", value);
    std::cout << string;

    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
  • I didn't realise that you could convert just using a stringstream like that, thanks. – MCSGaming Dec 07 '21 at 18:38
  • 1
    Instead of hard-coding the `"0x"` prefix, you can alternatively use `std::showbase` alongside `std::hex` with `std::ostringstream`, and use `"{:#x}"` for `std::format()`. – Remy Lebeau Dec 07 '21 at 18:55
  • @MCSGaming Having to use new/delete in (modern) C++ is usually an indication it can be done differently. https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines, check P.3. Enforcement – Pepijn Kramer Dec 07 '21 at 19:05
0

If you read the documentation carefully, you would see that you are trying to call the template overload of _itoa_s() that takes in a reference to a fixed-sized array:

template <size_t size>
errno_t _itoa_s( int value, char (&buffer)[size], int radix ); 

You would need to instead call the non-template overload that takes in a pointer and a size:

errno_t _itoa_s( int value, char * buffer, size_t size, int radix );

Try this:

int decValue = stoi(dec);

int hexLen = value.length();
int arraySize = hexLen + 1; // +1 for null terminator!

char* arrayPtr = new char[arraySize];

errno_t errCode = _itoa_s(decValue, arrayPtr, arraySize, 16);
if (errCode != 0)
{
    // error handling...
}
else
{
    string hexVal = arrayPtr;
    // use hexVal as needed...
}
delete[] charArrayptr;

Since you are trying to get the hex into a string, you can do away with the char* altogether:

int decValue = stoi(dec);

string hexVal;
hexVal.resize(value.length());

errno_t errCode = _itoa_s(decValue, &hexVal[0], hexVal.size()+1, 16);
if (errCode != 0)
{
    // error handling...
}
else
{
    hexVal.resize(strlen(hexVal.c_str())); // truncate any unused portion
    // use hexVal as needed...
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770