C++ 为什么我可以转换65535+;1到C+中的有效整数+;?

C++ 为什么我可以转换65535+;1到C+中的有效整数+;?,c++,integer,overflow,C++,Integer,Overflow,我有一个非常简单的程序: int main() { char* num = new char[5]; sprintf(num, "65536"); std::cout << "atoi(num): " << atoi(num) << "\n"; } intmain() { char*num=新字符[5]; sprintf(num,“65536”); std::cout在当前的PC系统上,int通常是32位甚至64位(除了一些较小的平台,如Ardu

我有一个非常简单的程序:

int main()
{
  char* num = new char[5];
  sprintf(num, "65536");
  std::cout << "atoi(num): " << atoi(num) << "\n";
}
intmain()
{
char*num=新字符[5];
sprintf(num,“65536”);

std::cout在当前的PC系统上,
int
通常是32位甚至64位(除了一些较小的平台,如Arduino)

因此,在您的系统上,
int
(或
unsigned int
)可能大于16位,65536不应溢出。您可以通过以下方式轻松检查:

std::cout << sizeof(int) << "\n";
因此,
sprintf()
将编写一个终止的
\0
文件,超过缓冲区,导致:

没有办法限制写入的字符数,这意味着 使用
sprintf
的代码容易发生缓冲区溢出

这应改为:

char* num = new char[6];

您的程序是否通过Valgrind或ASAN之类的内存调试器运行?请注意,“65536”不能放入字符[5]。您需要为空字符分配空间。如果无符号int错误,可能您对最大大小的假设是错误的?请检查
std::numeric_limits::max()
。还请注意,您有未定义的行为,因为
num
不是以null结尾的。@juanchopanza,所以看起来我使用的引用是错误的。最大无符号整数应该是
2147483647
。但是,
atoi()
在这种情况下仍然不会中断。我缺少什么概念?@n0pe它没有错也没有错。
无符号int
必须至少是16位。仅此而已。你必须检查它在你的平台上是什么。但它极有可能是32位。
int
通常是16位,而不是32位。如果你计算使用它的CPu核心数,则不是32位几十个,比32个代码< int >代码>几十年,还有64个或更奇特的现在——24或18位的“代码> int /Cube >。标准没有定义int或其他整数类型的特定位大小,但只定义了最小的范围。不确定C++中的什么,而在java中是int。是32位,在调用
sprintf
之前不需要终止
num
。问题不是缺少终止符,而是没有分配足够的条目(正如您明显注意到的).
sprintf
将很好地编写一个终止符-只是超出了范围。@Ibukun:可能有一个原因,它们应该是不同的语言。相同的语法/语法并不意味着相同的语义。顺便说一句,整数溢出是未定义的行为。因此它很可能会显示奇怪的结果。但是-承认-这不太可能。
char* num = new char[6];