使用 "new" 的 C++ 动态内存分配

c++ dynamic memory allocation using "new"

本文关键字:内存 分配 动态 new 使用 C++      更新时间:2023-10-16

我是c++新手,尝试自学(我有Java背景)。

有动态内存分配的概念,我可以分配给一个数组(例如)使用new

在C中(也在c++中),我有mallocrealloc正在这样做。在c++中,由于一些我无法理解的原因,他们添加了new

我读过很多关于普通数组进入堆栈而动态分配数组进入堆的区别。

所以我所理解的是,通过使用new,我在堆中分配空间,当完成一个函数时,不会自动删除,但会保持在那里,直到我最后,手动释放它。

我找不到在正常内存上使用动态内存分配的实际示例。

  1. 这是说,我不能分配内存通过运行时使用正常数组。好吧,可能我没有正确地理解它,因为当我试图创建一个普通的数组(没有new),其容量作为用户的输入(如arr[input]),它工作得很好。

我的意思是:

int whatever;
cin>>whatever;
int arr2[whatever];
for (int i = 0; i < whatever; i++) {
    arr2[i]=whatever;
    cout<<arr2[i];
}
  1. 我真的不明白为什么它被称为动态,而扩展数组容量的唯一方法是将其复制到new,更大的数组。

我明白Vector类(我还没有学过)使用起来要好得多。但是,我仍然不能离开这个知识缺口,我必须理解为什么它被称为动态数组,为什么我应该使用它而不是普通数组。为什么我要费心手动释放内存,当我不能真正扩展它,而只是复制到一个新的数组?

当你在编译时知道数组的大小时,你可以这样声明它,它将存在于堆栈中:

int arr[42];

但是如果你在编译时不知道大小,只在运行时知道,那么你不能说:

int len = get_len();
int arr[len];

在这种情况下,必须在运行时分配数组。在这种情况下,数组将驻留在堆上。

int len = get_len();
int* arr = new int[len];

当你不再需要内存时,你需要做一个delete [] arr

std::vector是一个可变大小的容器,允许您在运行时分配和重新分配内存,而不必担心显式地分配和释放它。

int len = get_len();
std::vector<int> v(len); // v has len elements
v.resize(len + 10); // add 10 more elements to the vector

对于静态分配,您必须将大小指定为常量:

  MyObj  arrObject[5];

对于动态分配,可以在运行时更改:

  MyObj  *arrObject = new MyObj[n];

newmalloc的不同之处在于new将为数组中的所有对象调用ctor,而malloc只是给您原始内存。

如果你想使用一个数组,而你在编译时不知道它的确切大小,那就需要动态内存分配。请看下面的例子,

int a[3] = {1,2,3};  //<= valid in terms of syntax;
然而,

int size = 3;
int a[size] = {1,2,3} //<= compile error

为了解决这个问题,

int* ArrayPtr = new int[size];

也,当释放它时,调用delete[] ArrayPtr;而不是单独调用delete,因为我们正在谈论释放内存块

在C(也在c++)我有malloc和realloc是这样做的。在c++中,由于某种我无法理解的原因,他们添加了"new"。

malloc和realloc接受要分配的字节数,而不是您想要分配的类型,并且也不调用任何构造函数(同样,它们只知道要分配的大小)。这在C中工作得很好(因为它实际上有更多的大小系统而不是类型系统),但是对于c++的复杂得多的类型系统,它就不行了。相比之下,new是类型安全的(它不像malloc那样返回void*),并且在返回之前构造为您分配的对象。

据说,当使用普通数组时,我不能通过运行时分配内存。好吧,可能我没有正确理解它,因为当我试图创建一个普通的数组(没有"new")时,它的容量是用户输入的(比如arr[input])。

这是一个编译器扩展(C99的一部分),它不是标准的c++。标准要求'普通'数组有一个在编译时已知的边界。然而,你的编译器似乎决定支持可变长度的"正常"数组。

我真的不明白为什么它被称为动态,因为扩展数组容量的唯一方法是将其复制到一个新的更大的数组中。

是动态的,因为直到运行时才知道它的大小(因此在不同的调用中可能不同)。编译时与运行时的区别在其他语言中是不常见的(至少在我的经验中),但对于理解c++是至关重要的。