我对仅声明变量时的区别感到有些困惑,例如:
int n;
并使用“new”动态地将内存分配给变量,例如:
int m = new int;
我刚刚从一个简单的链表项目中注意到,当我以节点对象的形式插入一个新值时,我必须动态创建一个新节点对象并将所需的值附加到它,然后将其链接到我的清单的其余部分。但是.. 在同一个函数中,我可以定义另一个节点对象,例如。节点类型 *N。并使用此指针遍历我的列表。我的问题是..当我们只声明一个变量时,内存不会立即分配..或者有什么区别?
谢谢!
尽可能选择自动存储分配的变量:
int n;
超过
int* m = new int; // note pointer
在您的情况下首选动态分配的原因是链接列表的定义方式。即每个节点都包含一个指向下一个节点的指针(可能)。因为节点必须存在于它们创建的位置之外,所以它们是动态分配的。
节点类型 *N。并使用此指针遍历我的列表
是的,你可以这样做。但请注意,这只是一个指针声明。您必须将其分配给有意义的东西才能实际使用它。
我的问题是..当我们只声明一个变量时,内存不会立即分配..或者有什么区别?
实际上,这两种情况都是定义,而不仅仅是声明。
int n;
创建一个未初始化int的自动存储;
int* n;
创建一个指向int. 它是悬空的,它没有指向有效的内存位置。
int* n = new int;
创建一个指针并将其初始化为包含未初始化的有效内存位置int。
int* n = new int();
创建一个指针并将其初始化为包含值初始化int(即0)的有效内存位置。
int m = new int;
实际上是不正确的。new返回一个指向它创建的内存的指针。它应该是
int *m = new int;
甚至更好:
int *m = new int();
它设置 m = 0 指向的变量的初始值。
此外,关于您的问题,大对象通常是使用指针创建的,以在按值从函数传递到函数时消除大型复制操作。当变量的生命周期需要比函数的范围更长时,也可以使用它们。
但是,对于在函数范围内使用并且在其他任何地方都没有用的变量,应该使用自动内存
int m;
不同之处在于,只有当编译器可以在编译时确定需要多少内存以及需要多长时间时,才能使用自动存储。通常自动变量将在堆栈上分配。
而对于动态分配的内存,程序员负责跟踪此信息。这通常在堆上分配。由于各种原因,使用堆内存通常会产生更大的开销,并且在分配堆内存但从不释放它的情况下存在内存泄漏的风险。
在您描述的链表示例中,您不太可能在编译时知道列表的长度(如果您知道,那么您可以只使用静态数组),这就是为什么您需要显式管理内存而不是而不是让编译器自动处理内存管理。但是函数返回后就不需要你用来遍历列表的指针了,所以它可以由编译器自动管理。