当您直接声明变量占用一块数据时,但是当您使用关键字new声明变量时,它会从“免费存储”初始化带有内存的指针,该存储基本上是未使用的内存。这些有什么区别?
int *p_int = new int;
int *p_int;
答案 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];
之类的操作,因为在编译时不知道要分配的数量。自动更简单,至少和动态一样快,因此默认为自动。除非:
但最后,在现代C ++中,我们尝试避免使用指针。必须手动delete
内存很烦人且容易出错。无论你多么勤奋,它都是内存泄漏的秘诀。对于动态数组,请使用std::vector
。要分配需要由许多事物共享的对象,请使用智能指针对象(unique_ptr
,shared_ptr
,weak_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
这是另一种情况,也只是一个项目,但在这种情况下,它是水,没有玻璃。