C++中的静态数组与动态数组

use*_*514 79 c++ arrays static allocation dynamic

C++中的静态数组和动态数组有什么区别?

我必须为我的班做一个任务,它说不要使用静态数组,只使用动态数组.我看过这本书和网上,但我似乎并不理解.

我认为静态是在编译时创建的,并且在运行时是动态的,但我可能会误以为内存分配.

你能解释一下C++中静态数组和动态数组之间的区别吗?

Mic*_*zek 91

本地数组在堆栈上创建,并具有自动存储持续时间 - 您不需要手动管理内存,但是当它们结束时它们会被销毁.它们必然具有固定的大小:

int foo[10];
Run Code Online (Sandbox Code Playgroud)

创建的数组operator new[]具有动态存储持续时间并存储在堆上(技术上称为"免费存储").它们可以有任何大小,但是你需要自己分配和释放它们,因为它们不是堆栈框架的一部分:

int* foo = new int[10];
delete[] foo;
Run Code Online (Sandbox Code Playgroud)

  • @Eddy:这取决于是否需要向量的情况 (21认同)
  • 这是正确的,但只是为了说明它是如何工作的.请不要在实际代码中执行此操作,而是使用std :: vector. (15认同)
  • @EddyPronk对于内存碎片原因,可以使用固定数组作为一种池.并非每种情况都需要堆,使用基于堆栈的数组有特殊的好处.你将std :: vector视为金锤,一种常见的反模式. (15认同)
  • @Casebash:在哪种情况下你更喜欢数组?"你应该总是喜欢使用矢量或deques而不是数组." - Herb Sutter(更特别的C++) (5认同)
  • @EddyPronk:我很确定Herb Sutter意味着动态数组,比如`int*foo = new int [N]`你必须自己`删除',因此在出现异常时要小心.静态数组没有这些问题. (4认同)
  • [最佳实践](http://fredosaurus.com/notes-cpp/newdelete/50dynamalloc.html)建议:不要忘记重置指针`foo = NULL;`******delete [] foo; `.因为在某些系统中,`delete`不会重置指针. (2认同)

Jos*_*ton 28

static是C和C++中的关键字,因此静态在应用于变量或数组时具有非常特定的含义,而不是一般描述性术语.为了加剧混乱,它在不同的背景下有三个不同的含义.因此,静态数组可以是固定的也可以是动态的.

让我解释:

第一个是C++特定的:

  • 静态类成员是未使用构造函数实例化或使用析构函数删除的值.这意味着必须以其他方式初始化和维护成员.static成员可能是初始化为null的指针,然后在第一次调用构造函数时分配.(是的,这将是静态的和动态的)

两个继承自C:

  • 在函数内,静态变量是在函数调用之间保留其内存位置的变量.它是静态的,因为它只被初始化一次并在函数调用之间保留它的值(使用静态使函数不可重入,即不是线程安全的)

  • 在函数外部声明的静态变量是全局变量,只能在同一个模块中访问(源代码文件与任何其他#include)

你想问的问题(我想)是动态数组和固定数组或编译时数组之间的区别.这是一个更简单的问题,编译时数组是事先确定的(编译程序时)并且是函数堆栈帧的一部分.它们在main函数运行之前分配.动态数组在运行时使用"new"关键字(或来自C的malloc系列)进行分配,并且事先不知道它们的大小.在程序停止运行之前,动态分配不会自动清除.

  • +1,你的答案是最准确和准确的,应该收到更多的选票. (3认同)

Ben*_*ins 11

我认为你班上使用的语义令人困惑."静态"可能意味着什么只是"恒定大小",而"动态"可能意味着"可变大小".在那种情况下,一个恒定大小的数组可能如下所示:

int x[10];
Run Code Online (Sandbox Code Playgroud)

并且"动态"的只是允许在运行时增加或减少底层存储的任何类型的结构.大多数情况下,std::vectorC++标准库中的类就足够了.像这样使用它:

std::vector<int> x(10); // this starts with 10 elements, but the vector can be resized.
Run Code Online (Sandbox Code Playgroud)

std::vectoroperator[]定义,因此您可以使用与数组相同的语义.


Jag*_*ath 8

静态数组在编译时分配内存,内存在堆栈上分配.然而,动态数组在运行时分配内存,内存从堆分配.

int arr[] = { 1, 3, 4 }; // static integer array.   
int* arr = new int[3]; // dynamic integer array.
Run Code Online (Sandbox Code Playgroud)

  • 全局数组是一个静态数组,它是在数据部分实现的,而不是从堆栈实现的. (4认同)

Z b*_*son 8

明确定义术语的含义非常重要.遗憾的是,静态和动态数组的含义似乎有多种定义.

静态变量是使用静态内存分配定义的变量.这是一个独立于C/C++的通用概念.在C/C++中,我们可以创建具有全局,文件或本地范围的静态变量,如下所示:

int x[10]; //static array with global scope
static int y[10]; //static array with file scope
foo() {
    static int z[10]; //static array with local scope
Run Code Online (Sandbox Code Playgroud)

自动变量通常使用基于堆栈的内存分配来实现.可以用C/C++创建一个自动数组,如下所示:

foo() {
    int w[10]; //automatic array
Run Code Online (Sandbox Code Playgroud)

什么这些阵列,x, y, zw具有的共同点是,大小为它们中的每被固定,并且在编译时间被定义.

理解自动数组和静态数组之间区别的重要原因之一是静态存储通常在目标文件的数据部分(或BSS部分)中实现,编译器可以使用绝对地址来访问数组基于堆栈的存储是不可能的.

动态数组通常意味着什么不是可调整大小的,而是使用动态内存分配实现的,具有在运行时确定的固定大小.在C++中,这是使用new运算符完成的.

foo() {
   int *d = new int[n]; //dynamically allocated array with size n     
Run Code Online (Sandbox Code Playgroud)

但是可以使用以下命令创建一个在运行时定义的修复大小的自动数组alloca:

foo() {
    int *s = (int*)alloca(n*sizeof(int))
Run Code Online (Sandbox Code Playgroud)

对于真正的动态数组,应该使用类似std::vectorC++(或C中的可变长度数组).

OP问题中的任务意味着什么?我认为很明显,所需要的不是静态或自动数组,而是使用new运算符进行动态内存分配或使用例如非固定大小的数组std::vector.