c ++动态内存分配使用" new"

时间:2014-08-01 21:15:42

标签: c++ memory-management

我是C ++的新手,试图自己学习(我有Java背景)。

我可以使用new将这个动态内存分配概念分配给一个数组(例如)。

在C(以及C ++中)我已经mallocrealloc这样做了。在C ++中,由于某些我无法理解的原因,他们添加了new

我已经阅读了很多关于在动态分配的数组进入堆时进入堆栈的正常数组之间的区别。

所以我理解的是,通过使用new我在堆中分配空间,当完成一个函数时不会自动删除,但是它会保留到原来的位置,直到它为止。我终于,手动释放它。

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

  1. 它说我在使用普通数组时无法通过运行时分配内存。好吧,可能我没理解它是正确的,因为当我尝试创建一个普通数组(没有new)并且用户输入的容量(如arr[input])时,它工作正常精细。
  2. 这就是我的意思:

    int whatever;
    cin>>whatever;
    
    int arr2[whatever];
    
    for (int i = 0; i < whatever; i++) {
        arr2[i]=whatever;
        cout<<arr2[i];
    
    }
    
    1. 我没有真正理解为什么它被称为动态,因为扩展数组容量的唯一方法是将其复制到new更大的数组。
    2. 我知道Vector类(我还没有学过)更好用。但是,我仍然不能让知识的差距开始,我必须理解为什么它被称为动态,为什么我应该使用它而不是正常的数组。 当我无法真正扩展内存但只将其复制到新阵列时,为什么还要手动释放内存呢?

4 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:1)

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

  MyObj  arrObject[5];

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

  MyObj  *arrObject = new MyObj[n];

newmalloc之间的区别在于new会为数组中的所有对象调用ctor,而malloc只会为您提供原始内存。

答案 2 :(得分:1)

如果你想使用一个数组并且你不知道编译时的确切大小,那就是当动态内存分配步入时。请参阅下面的例子,

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,因为我们正在谈论此时释放内存块。

答案 3 :(得分:1)

  

在C(以及C ++中)我已经有了malloc和realloc。在C ++中,他们已经添加了&#34; new&#34;出于某种原因,我无法理解。

malloc和realloc使用要分配的字节数而不是要分配的类型,也不要调用任何构造函数(同样,它们只知道要分配的大小)。这在C中运行良好(因为它实际上具有比类型系统更多的大小系统),但是对于C ++而言,类型系统更加复杂,它不足。相反,new是类型安全的(它不像malloc那样返回void *)并在返回之前构造为你分配的对象。

  

它说我在使用普通数组时无法通过运行时分配内存。好吧,可能我没理解它是正确的,因为当我尝试创建一个普通数组(没有&#34; new&#34;),其容量由用户输入(如arr [input])。它运作良好。

这是一个编译器扩展(和C99的一部分),它不是标准的C ++。该标准要求正常的&#39;数组有一个在编译时已知的边界。但是,您的编译器似乎决定支持可变长度&#39; normal&#39;阵列无论如何。

  

我没有真正理解为什么它被称为动态,因为扩展数组容量的唯一方法是将它复制到一个新的更大的数组。

它的动态是你不知道运行时的大小(因此在不同的调用中可能会有所不同)。编译时间与运行时间之间的区别是您不会经常在其他语言中运行(至少在我的经验中),但它对于理解C ++至关重要。