为什么我会在没有malloc的情况下完成相同的工作时使用malloc,如下所示。
#include <stdio.h>
#include <conio.h>
struct node {
int data;
struct node *l;
struct node *r;
};
int main(){
//Case 1
struct node n1;
n1.data = 99;
printf("n1 data is %d\n", n1.data);
//Case 2
struct node *n2 = (struct node *) malloc (sizeof(struct node));
n2 -> data = 4444;
printf("n2 data is:%d\n",n2 -> data);
free(n2);
return (0);
}
答案 0 :(得分:9)
为什么我会在没有malloc的情况下完成相同的工作时使用malloc 下面..
使用malloc,在堆上分配内存,没有malloc,你将结构放在堆栈内存中。
我很难理解n1是如何初始化的 到内存位置能够存储数据(99)。
是否初始化,当您分配数据n1.data = 99;
时,它会被存储。
2)何时使用案例1以及何时使用案例2
当您知道将在受限范围内使用结构对象时,使用情况1,并且不会超出其范围引用结构数据。
在您将在多个地方使用您的结构时使用案例2,并且您愿意手动(并仔细!)管理它的内存。这种方法的优点是,您可以在程序范围的某个部分创建和初始化结构,并创建指针并传递指针,因为传递4字节指针比传递结构本身更有效。
答案 1 :(得分:3)
int main() {
struct node n1;
n1.data = 99
这会在堆栈上(在main
的框架中)保留相当于struct node
大小的空间。这被称为本地,它只存在于main
的上下文中。
struct node *n2 = (struct node *) malloc (sizeof(struct node));
这是堆上的分配。无论你在哪个函数上下文,这个内存都存在。这通常称为“动态分配”。
这些node
结构是linked list的基础,可以随意添加,删除,重新排序等节点。
另见:
答案 2 :(得分:2)
在第一种情况下,在堆栈上分配内存。当变量n1
超出范围时,将释放内存。
在第二种情况下,在堆上分配内存。您必须显式释放内存资源(正如您对free
所做的那样)。
经验法则可以是将堆栈分配的内存用于有限大小的本地临时数据结构(堆栈只是计算机内存的一部分,每个平台不同)。将堆用于要保留或大的数据结构。
Google搜索stack and heap会为您提供更多信息。
答案 3 :(得分:1)
通常只使用malloc,如果你不知道应用程序运行之前需要的内存大小。
您的代码是正确的,但您无法动态分配内存。如果要在node.date中保存测量值并且您不知道,您将捕获多少度量,该怎么办?然后你必须在你采取的每项措施上使用一些新的记忆。
如果在运行时(直接在代码中)定义所有节点,则无法保存比之前定义的更多的度量。
在c中搜索链接列表,你会发现一些很好的例子。
答案 4 :(得分:0)
您的数据类型看起来像树中的节点。使用malloc
进行树节点分配的两个主要原因是
分配任意数量的节点。树节点的数量通常是运行时值。由于这个原因,不可能为这样的节点声明适当数量的局部变量,因为所有局部变量都必须在编译时声明。同时,可以在运行时调用malloc
多次,根据需要分配尽可能多的节点对象。
确保在本地对象的生命周期结束时(即在块的结尾处)不自动销毁节点。由malloc
分配的对象永远 ,即直到您通过调用free
明确销毁它们。这样的对象将超越块边界和功能边界。对于本地对象,没有什么比这更好的了,因为本地对象在它们的块结束时会自动销毁。
您的代码示例不依赖于动态分配的任何好处,因为它确实会创建一个真正的树。它只是声明为单个节点。但是,如果您尝试构建具有运行时节点数的完整树,您将立即意识到通过将节点声明为本地对象是不可能的。您将不可避免地必须使用malloc
分配您的节点。
你的“如何n1未初始化到内存位置能够存储数据”这个问题必然会引起一些混乱。 struct node n1;
是一个对象 definition ,这意味着它为n1
分配了一个内存位置。这正是对象定义的目的。