C/C++分配

C/C++ Allocation

给一个数X,将X个数读入一维数组,下面哪种方式最好(执行时间最快)?

请注意 X 是 1 到 1000000 之间的数字

scanf("%d", &x);
int array[x];
//continue reading X numbers into array

scanf("%d", &x);
int array[1000000];
//continue reading X ...

scanf("%d", &x);
int * array = malloc(x*sizeof(int));
//same as above
free(array);

还是C++的动态分配方式?

注意 1:我是通过手机发布的 phone,我希望上面代码的格式没问题,如果不行,我希望有人 (<3) 可以编辑它,因为它从 phone.

缩进代码很痛苦

注2:如何测试我上面的要求?

这段代码会出现编译错误:

scanf("%d", &x);
int array[x];
在这种情况下,

x 应该在编译时已知。

当使用 int array[1000000] 时,你在栈上分配内存,而不是在堆上,所以这是与 mallocnew operator 相比的根本区别。它会更快,因为它实际上只需要一个 CPU 修改堆栈指针的命令。

如果比较mallocnewmalloc会更快,因为new最终会在里面调用malloc。但是性能增益会很小,用这种方式优化你的c++程序不值得,当你需要分配动态内存时使用c++。

自从出现 scanf(并且评论假设还有一百万次调用 scanf)关于内存分配与 "Which is fastest?" 结合的任何问题都可以普遍回答: "Yes"(读作:无关)。

虽然自动存储 ("stack allocation") 通常比免费存储更快,但与您在 scanf 中花费的时间相比,它完全微不足道。话虽这么说,通常(不一定,但通常)动态 deallocation 很慢,而不是分配。

该代码一般需要注意几点:

  1. 从某些外部源(文件、网络、argv 等)读取整数并根据该数字进行分配而不首先进行健全性检查是非常糟糕的业力。这势必有一天会引起一个问题,就是现实世界中有多少现有的漏洞利用应运而生。不要盲目地相信你从某个地方得到的任何数字都是自动有效的。即使没有恶意,事故 仍可能提供无效数字,这将导致灾难性故障。
  2. 在堆栈上分配一个非常量大小的数组将在最新版本的 C 下工作,并且 "work" 如果您使用 GCC,即使在 C++ 下也可以作为扩展,但在 C++ 中通常不允许这样做(意思是它将无法编译。
  3. 分配一百万个整数意味着大约 4MB 的内存,这对您的最大堆栈大小(通常只有 1MB)来说是相当苛刻的。 预计会发生堆栈溢出
  4. 分配 未知 个整数(但预计数量最多为一百万)类似于 (3)。
  5. 关于 (3) 和 (4) 的最糟糕的事情是 它实际上可能会成功 。这可能意味着您的程序稍后会在一段完全不相关的无辜代码中意外崩溃(遇到堆栈溢出)。你会想知道为什么会发生这种情况,因为崩溃的代码看起来完全有效(确实如此!)。