静态与动态数组C ++

时间:2018-02-19 12:34:17

标签: c++ arrays dynamic static

C ++的编译器可能表现不同。由于可以使用以下方法声明C ++中的数组:

方法A:

int size;
cout << "Enter size of array: ";
cin >> size;

int x[size];  
for (int i = 0; i < size; i++)
{
    //cout << "x[" << i << "] = ";
    x[i] = i + 1;
}  

方法B

int size;
cout << "Enter size of array: ";
cin >> size;

int *x = new int[size];  
for (int i = 0; i < size; i++)
{
    //cout << "x[" << i << "] = ";
    x[i] = i + 1;
}

通过在运行时中获取用户的输入,两者都正常工作。我知道,使用方法 B ,我们必须删除x之类的delete [] x

  • 为什么要使用int *x = new int[size];,如果两者的服务相同 目的?
  • 使用new有什么好处?

以下是我正在测试的代码段:

#include<iostream>
using namespace std;

int main()
{
    int size;
    cout << "Enter size of array: ";
    cin >> size;

    //int *x = new int[size];
    int x[size];

    for (int i = 0; i < size; i++)
    {
        //cout << "x[" << i << "] = ";
        x[i] = i + 1;
    }

    cout << endl << "Display" << endl;
    for (int i = 0; i < size; i++)
    {
        cout << "x[" << i << "] = " << x[i] << endl;
    }  
    return 0;  
}

2 个答案:

答案 0 :(得分:3)

C ++标准没有定义方法A,但在ISO C99中允许它,GCC也支持它在C ++模式下。来自https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

  

ISO C99允许使用可变长度自动数组,并且作为   扩展GCC在C90模式和C ++中接受它们。这些数组是   声明像任何其他自动数组,但长度是   不是一个恒定的表达。存储分配在   当块范围包含时,声明和释放   声明退出。

我刚刚在这里找到了一些相关的讨论:Variable Length Arrays in C++14?

答案 1 :(得分:2)

简单的答案是:堆栈空间有限。您可以期望能够在堆上分配1GiB,但您不能指望能够在堆栈上分配相同的数量。 / p>

第一个变体int x[size];使用堆栈。因此,如果size很大,您可能会发现程序崩溃并出现段错误。通过简单地减少CPU的堆栈指针寄存器来进行分配。如果你减少太多,内核只会将你对堆栈内存的下一次访问视为越界访问,并终止你的进程。在实际拍摄之前无法检测到这种情况,或者无法以有序的方式从中恢复。内核只是在没有警告的情况下射击你。

第二个变体int* x = new int[size];使用堆。因此,只要有足够的可用RAM来支持分配,您就可以期望分配成功。 operator new()将以有序的方式明确地向内核询问内存,并且内核将以有序的方式遵守或发出大量内存的不可用性。如果出现错误,operator new()将继续抛出异常,您可以随意捕获并处理。

<强>除了
如果您的内核过度使用其内存(就像任何现代Linux一样),那么保证在发生错误时获得异常。当operator new()在没有实际提供任何内存的情况下询问内存时,内核将只回复“ok”,并且可能稍后发现它无法履行其承诺。当发生这种情况时,它将调用OOM杀手(Out-Of-Memory杀手),它基于一些启发式射击一些进程。因此,永远不要期望不要因为过多的内存消耗而被拍摄。

这实际上是一个能够实际使用所有可用内存的优化:首先,许多程序实际上并没有使用它们分配的所有内存(比如分配一个大缓冲区,但只使用它的一部分)。另一方面,不可能知道哪个COW(写时复制)映射页面实际上需要复制。内核不知道将来需要多少内存,它只知道它当前是否有足够的内存。

<强> TL; DR:
仅当您可以证明int x[size];永远不会超过最小值时才使用size。如果size大约是10到100(并且类型本身并不是非常大),那就去吧。在所有其他情况下使用int* x = new[size];