直接声明变量和使用关键字new之间有什么区别?

时间:2014-04-22 16:50:06

标签: c++

当您直接声明变量占用一块数据时,但是当您使用关键字new声明变量时,它会从“免费存储”初始化带有内存的指针,该存储基本上是未使用的内存。这些有什么区别?

int *p_int = new int;
int *p_int;

4 个答案:

答案 0 :(得分:4)

存在很多差异。

动态分配

int *x = new int;

这被称为"动态分配"。

new int在堆上分配内存以存储int,并返回此内存的地址(指针)。因此,在此声明之后,x将是一个内存地址,如0x200fd2a11或其他任何内容。它指向的内存可以用作整数。这是相同的例子,有点扩展:

int *x;// declare a pointer to an integer. at this stage, x is uninitialized and does not point to anything.
x = new int;// set x to point to a newly allocated int.
*x = 4;// now we are using the integer for the first time, setting it to 4.
delete x;// you must delete dynamically allocated memory, or you'll have a memory leak.

请注意,您在此处理两个不同的值:指针和整数。

另请注意,当您完成操作时,必须delete指针,以释放内存。

自动分配

好的让我们继续前进并描述它与以下内容的区别:

int x;
x = 4;

此处,x是" auto变量"。最大的根本区别在于它的存储空间是在堆栈上分配的。以下是动态和自动分配之间的差异列表

  • 自动变量在离开范围时会自动清除。这意味着您不需要费心使用delete,但这意味着您无法控制其生命周期。
  • 堆栈内存是固定大小的。因此,如果您尝试int x[100000000];,您的应用可能会崩溃。
  • 自动变量不处理指针间接。您可以直接访问该值,而无需取消引用指针(类似*x = 4;中的星号)。你可以x = 4;
  • 自动变量'大小必须在编译时知道,因为生成代码来处理堆栈。因此,您不能执行int x[y];之类的操作,因为在编译时不知道要分配的数量。

我何时使用动态v。自动?

自动更简单,至少和动态一样快,因此默认为自动。除非:

  1. 编译时未知大小
  2. 或者,尺寸是"大"。比如,大于几百字节,我通常会移动到堆。它有助于调试并且更安全。
  3. 或者,生命周期未绑定到代码中的范围。例如,如果您需要在函数中分配对象,并在该函数返回后继续生效。
  4. 在实践中

    但最后,在现代C ++中,我们尝试避免使用指针。必须手动delete内存很烦人且容易出错。无论你多么勤奋,它都是内存泄漏的秘诀。对于动态数组,请使用std::vector。要分配需要由许多事物共享的对象,请使用智能指针对象(unique_ptrshared_ptrweak_ptr)。几乎总是比使用原始指针更安全。

答案 1 :(得分:0)

int *p_int = new int;创建一个指针*p_int,并将其指向堆中新分配的空间(免费商店)。

int *p_int;只创建一个指针*p_int,但不指向任何特定的内存位置 - 它指向一个破坏的位置。

当您执行*p_int = 42;之类的操作时,它会在第一种情况下将该已分配块的值设置为42。 第二种情况,因为它没有指向特定的地方,可能会产生错误的结果。

答案 2 :(得分:0)

在块中声明的变量(通常)在函数的堆栈帧内分配。它的寿命限于包含它的功能或块的寿命。退出该函数时,将释放堆栈中的内存。对于递归函数,每个函数块都有自己独立的变量版本。

当使用" new"分配变量时,对象的内存将分配给免费商店。它的生命周期是使用"删除"释放内存。必须跟踪这些类型的分配,因为它们不会自动回收。这些对于必须超过分配函数生命周期的对象非常有用。

最大的不同就是生命和所有权。

当您通过new分配内容时:

int* p_int = new int{42};

实际上,您正在分配两个对象,一个大小为int的内存块,初始化为值42,以及一个指向内存块地址的指针指向int。您必须跟踪内存块的生命周期并使用delete将其释放。记忆" p_int"它本身(不是它指向的)在堆栈中,并在你退出时被释放。

答案 3 :(得分:0)

int *p_int = new int;

这是两件事。指针变量和实际对象。把它想象成一个带水的玻璃杯。

int *p_int;

这只是一个变量,没有实际的对象。把它想象成没有水的玻璃。

int my_int

这是另一种情况,也只是一个项目,但在这种情况下,它是水,没有玻璃。