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