【问题标题】:What is the best practice of using itoa()使用 itoa() 的最佳实践是什么
【发布时间】:2012-01-10 03:51:14
【问题描述】:

当我使用 itoa() 时,它需要一个 char* _DstBuff,这里的最佳做法是什么?

#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;
}

输出是: 100 100 100

那么有人可以在这里解释char *b = new char; 和char *c = new char[10]; 之间的区别吗?

我知道char *c 会动态分配 10 个字符,但这意味着 char *b 只会动态分配 1 个字符,如果我是对的,为什么输出都是正确的?

实际上,a、b 或 c 的最佳实践是哪个?

【问题讨论】:

  • 在编写 C++ 时为什么要使用itoa?
  • @Cody:因为itoa 比标准库中的其他实用程序更强大(支持许多不同的基础)并且效率更高。
  • 鉴于没有人提到它...#include &lt;stdlib.h&gt;long int strtol(const char *nptr, char **endptr, int base);long long int strtoll(const char *nptr, char **endptr, int base);

标签: c++ memory-leaks memory-management itoa


【解决方案1】:

最佳实践:根本不要使用它。

为什么?因为它不在标准中。

我应该怎么做?使用std::to_string。

(如果您真的无法使用itoa,那么请使用大型本地静态缓冲区,例如char[512] 左右——如果您想真的安全,您可以使数组大小为sizeof(unsigned long long int) * CHAR_BIT + 2 或类似的大小,以便它始终可以容纳以任何基数表示的任何数字,加号。)

【讨论】:

  • std::to_string 在 C++11 我现在用的是 VC6,有没有替代品?
  • @shengy:您可以通过 stringstreams、strstreams、使用 Boost.lexical_cast 或 sprintf。对于任意基础,您也可以轻松滚动自己的基础。我个人不止一次地为此发布过代码,尽管它真的非常简单。
  • @shengy,一个选择是获得一个像样的编译器 :-) 繁荣,谢谢,我整个星期都在这里。
  • VC6,哇。考虑升级到现代编译器?从长远来看,这将为您节省大量工作。
  • 这是一个 related 答案,您应该可以将其修改为转换数字的内容(每轮只需将数字除以 16),您还可以将其推广到任何基数(替换 16通过所需的基地)。
【解决方案2】:

在this question I posed 中,您会发现十几个 将整数转换为字符串的高效函数,所有这些函数都分配并返回std::string,因此您不必担心缓冲区溢出.并且其中的几个选项起泡快。

【讨论】:

    【解决方案3】:

    您所描述的不是内存泄漏,而是buffer overflow。

    基本上,你很幸运。如果你只分配一个字符,然后写入四个字符,你就会超出分配给你的内容,这是一个错误。

    【讨论】:

      【解决方案4】:

      cout &lt;&lt; b &lt;&lt; endl; : 不正确,是缓冲区溢出。 因为您分配 1 个字节的内存来包含一个字符。但是,你在上面写上itoa() 10+1chars。

      所以你必须分配:char * d = new char[11]; // 10 chars + '\0'(end of string char).

      然后使用itoa(num , d , 10);

      另外itoa()是非标准的,所以我更喜欢使用标准的sprintf(d,"%d",num);

      正如下面评论中所说,如果您不需要char*,您可以使用std::string。使用

      string d = std::to_string(num);
      

      【讨论】:

      • 1/ 它是sprintf 和f。 2/ 这适用于某些数据类型,但 C++ 方式适用于字符串流。 sprintf 是遗留 C 的东西,不是类型可扩展的。 3/ 不要在喝醉的时候发帖(“tocontain”和“whit”):-)
      猜你喜欢
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多