0

When I use itoa() it needs a char* _DstBuff, what is the best practice here?

#include "stdafx.h"
#include <iostream>

using namespace std;

int main()
{
  int num = 100;

  // I'm sure here is no memory leak, but it needs to know the length.
  char a[10]; 

  // will this causue memory leak? if yes, how to avoid it?
  // And why can itoa(num, b, 10); be excuted correctly since b
  // has only allocated one char.
  char *b = new char; 

  // What is the difference between char *c and char *b
  // both can be used correctly in the itoa() function
  char *c = new char[10]; 

  itoa(num, a, 10);
  itoa(num, b, 10);
  itoa(num, c, 10);

  cout << a << endl;
  cout << b << endl;
  cout << c << endl;
   return 0;
}

the output is: 100 100 100

So could anyone explain the differenct between char *b = new char; and char *c = new char[10]; here?

I know char *c will dynamiclly allocate 10 chars, but that means char *b will only dynamically allocate 1 char, if I'm right about this, why is the output all correct?

actually which is the best practice of a, b, or c?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
shengy
  • 9,461
  • 4
  • 37
  • 61
  • 3
    Why would you be using `itoa` when writing C++ anyway? – Cody Gray - on strike Jan 10 '12 at 03:55
  • 1
    @Cody: Because `itoa` is more powerful (supports many different bases) and much much more efficient than other utilities in the standard library. – Ben Voigt Jan 10 '12 at 04:24
  • Given that nobody mentioned it... `#include ` `long int strtol(const char *nptr, char **endptr, int base);` `long long int strtoll(const char *nptr, char **endptr, int base);` – Avio Nov 13 '12 at 10:26

4 Answers4

6

Best practice: Don't use it at all.

Why? Because it's not in the standard.

What should I do instead? Use std::to_string.

(If you're really stuck having to use itoa, then use a large local static buffer, like char[512] or so -- if you want to be really really safe you can make the array size sizeof(unsigned long long int) * CHAR_BIT + 2 or something like that so it can always hold any number expressed in any base, plus sign.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • std::to_string is in C++11 I'm using VC6 right now, is there any alternates? – shengy Jan 10 '12 at 04:04
  • @shengy: You could go via stringstreams, strstreams, use Boost.lexical_cast, or `sprintf`. For arbitrary bases you can easily roll your own, too. I've personally posted code for that on more than one occasion, though it's really very straightforward. – Kerrek SB Jan 10 '12 at 04:05
  • 2
    @shengy, one altenative is to get a decent compiler :-) Boom boom, thanks, I'm here all week. – paxdiablo Jan 10 '12 at 04:08
  • 2
    VC6, wow. Considered upgrading to a modern compiler? That will save you a lot of work in the long run. – Cody Gray - on strike Jan 10 '12 at 04:08
  • Here's one [related](http://stackoverflow.com/a/8024386/596781) answer which you should be able to modify into something to convert a number (just divide the number by 16 each round), and you can also generalize it to any base (replacing 16 by the desired base). – Kerrek SB Jan 10 '12 at 04:12
  • I can't upgrade to a new complier, my company uses VC6 for a long time, and there are too many code to validate in this case – shengy Jan 10 '12 at 05:49
2

In this question I posed, you'll find a dozen efficient functions for converting an integer into a string, all of which allocate and return a std::string so you needn't worry about buffer overflow. And several options in there are blistering fast.

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1

What you are describing is not a memory leak, but rather a buffer overflow.

Basically, you are getting lucky. If you allocate only one character, but then write four characters to it, you are overrunning what has been allocated to you, and this is a bug.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
0

cout << b << endl; : is incorrect, it is a buffer overflow. because you allocate 1 byte of memory to contain one char. but, you write on it with itoa() 10+1chars.

so you have to allocate : char * d = new char[11]; // 10 chars + '\0'(end of string char).

then use itoa(num , d , 10);

in addition itoa() is non standard, so i prefer to use the standard sprintf(d,"%d",num);

and as said in the comment below, if you dont need char* and you can use std::string. use

string d = std::to_string(num);
Hicham
  • 983
  • 6
  • 17
  • 1
    1/ It's `sprintf` with an `f`. 2/ That'll work for certain data types, but the C++ way is with string streams. `sprintf` is legacy C stuff, not type-extensible. 3/ Don't post when you're intoxicated ("tocontain" and "whit") :-) – paxdiablo Jan 10 '12 at 04:05