【问题标题】:How is 'new' dynamic in C++C ++中的“新”动态如何
【发布时间】:2013-07-09 08:30:58
【问题描述】:

如何使用“新”被认为是动态的?我知道它被放在堆上,返回一个指针并保持不变,但我还没有认识到它在分配方面的“动态”性质。

在以下情况下,两个数组都是在运行时分配的,即使是静态方法。所以我看不出有什么不同。而且我不相信动态增加/缩小分配是可能的,对吗?

int size = 0;
std::cout << "enter size: ";
std::cin >> size;

int* array_d = new int[size];   // "dynamic" allocation
int array_s[size];              // static allocation correct?

【问题讨论】:

  • 动态和静态在这个例子中被简单地使用了。这种“静态”分配与实际的静态分配无关——它只是暗示这个数字是一个常数。 (顺便说一句,代码无效,因为size 不是常量,所以arrray_s 是错误的)
  • 这两种代码都不是你应该在 C++ 中使用的代码——但是出于非常不同的原因(一个是非法的,另一个是坏的)。
  • 代码为我编译和运行(gcc 版本 4.2.1)。为什么都是坏代码?另外我仍然不确定“新”是如何动态的,因为两者都是在运行时设置的,并且都不能在运行时增长/缩小。
  • @user1229895 当你传递选项-pedantic时它不会编译。该代码是非法的 C++,GCC 只是碰巧允许它。 new 是手动内存管理,脆弱且容易出错,在现代 C++ 中没有任何作用。
  • @KonradRudolph 感谢您指出这一点,那么应该使用什么来代替 new 呢?

标签: c++ arrays memory-management new-operator


【解决方案1】:

在 C++ 中有三种类型的内存分配。有静态分配:

int x[100];

void foo() {
    static int y[100];
}

这里,数组的大小在编译时是已知的,每个进程都有一个数组的实例,所以数组可以由编译器静态分配:它们可以在二进制文件中获得固定的位置和地址结果过程的空间。

然后是自动分配:

void foo() {
    int z[100];
    // or even:
    //auto int z[100];
    // though nobody writes that
}

这大致介于静态和动态之间。大小必须在编译时知道,但每个函数调用都有一个实例。通常,实例分配在堆栈的当前顶部附近。

最后是动态分配:

void foo(size_t n) {
    int *p = new int[n];
    delete[] p;
}

这里,数组的大小和在内存中的位置都是动态确定的,即在运行时。

【讨论】:

  • 感谢您解决不同的分配问题。所以它唯一的动态是它在运行时设置,而不是它可以动态增长?并且这两个示例不是在运行时设置的吗?
  • @user1229895:有哪些例子?其中有三个。不,分配不能随着new 而增长。
  • 对不起,我指的是我给出的两个例子。不过,有人告诉我其中一个在正常操作下在技术上是无效的。
【解决方案2】:

用 new 分配的内存是动态的,因为要分配的内存量是在运行时决定的。因此,无法保证它会成功。

静态数组声明具有在编译时确定的常量大小,您通常不会担心分配会以任何方式失败。

也就是说,如果堆栈溢出,分配在堆栈上的本地数组可能会失败,但这通常不是问题。

【讨论】:

  • 感谢您指出潜在的陷阱。我看到它是动态的,因为它是在运行时设置的,但从技术上讲,这两个示例都不是这样吗?
  • 在数组声明中使用非常量大小是 C99(可变长度数组)的一个特性。我不相信它在 C++ 中有效(如果你需要那种功能,你应该使用向量),但 GCC 支持它作为 extension。因此,如果您要声明这样的数组,那么从技术上讲,它们都是动态的,但在标准 C++ 和 C 的早期版本中这是不可能的。
  • 谢谢,您的评论就是答案...它解决了问题,我很欣赏向量的建议。
【解决方案3】:
int array_s[size]; 

这不是有效的 c++,至少在 c++03/11 中是无效的,数组必须具有固定大小,通过在堆栈上保留通常在编译时分配的空间来分配。

第一个是动态的,因为您可以在运行时分配不同数量的内存,第二个根本不是有效的 c++,只有固定数量是合法的,这就是为什么它不被视为动态的原因

【讨论】:

  • 没有收到 gcc 4.2.1 版的警告。所以声明'const int size;'将使第二个示例'int array_s [size];'有效吗?
  • 这将使它有效。 gcc 有一个非标准扩展,允许您使用非常量值作为大小,但这不是标准 c++
【解决方案4】:

第一个数组的大小可能会在运行时改变,所以它是“动态的”。 第二个数组的大小必须在编译时知道,因此它是“静态的”。

【讨论】:

  • 呃,不,数组可能会被再次分配,但大小不同,但一旦分配,它的大小是固定的。它是动态的,因为内存不是在“构建时”分配的(当然,这也适用于第二种情况,但这不是有效的标准 C++)。
  • 你说得对,我想说的是size参数可能在分配时间之前就改变了,不需要在编译时就知道。
  • 所以最初分配给 'int array_s[size];'在编译期间使用大小的默认值?然后在运行时 cin 动态覆盖它?这不是实现了 new 应该做的事情吗(没有它的额外内容返回一个指针并在堆上)?
猜你喜欢
  • 2020-04-25
  • 1970-01-01
  • 2014-12-04
  • 1970-01-01
  • 2017-07-08
  • 2013-01-17
  • 2012-09-09
  • 1970-01-01
  • 2012-12-24
相关资源
最近更新 更多