11

为什么在没有 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);
}
  1. 我很难理解未初始化为内存位置的 n1 如何能够存储数据 (99) 。
  2. 什么时候用case 1,什么时候用case 2。
4

5 回答 5

12

为什么在没有 malloc 的情况下完成相同的工作时我会使用 malloc,如下所示..

您使用 malloc 在堆上分配内存,而没有 malloc,您将 struct 放置在堆栈内存中。

我很难理解未初始化为内存位置的 n1 如何能够存储数据 (99) 。

初始化与否,当您分配数据时n1.data = 99;,它会被存储。

2)什么时候用case 1,什么时候用case 2

当您知道将在受限范围内使用结构对象并且不会在其范围之外引用结构数据时,使用案例 1。

当您将在多个地方使用您的结构并且您愿意手动(并且小心!)管理它的内存时,使用案例 2。这种方法的优点是,您可以在程序范围的某些部分创建和初始化结构,然后创建指针并传递指针,因为传递 4 字节指针比传递结构本身效率更高。

于 2013-10-10T06:49:03.740 回答
4
int main() {
    struct node n1;
    n1.data = 99

这会在堆栈上(在的框架中)保留main与 a 大小相等的空间struct node。这被称为本地,它只存在于main.

struct node *n2 = (struct node *) malloc (sizeof(struct node));

这是堆上的分配。无论您在什么函数上下文中,此内存都存在。这通常称为“动态分配”。

这些node结构是链表的基础,可以随意添加、删除、重新排序等节点。

也可以看看:

于 2013-10-10T06:40:59.203 回答
3

在第一种情况下,内存是在堆栈上分配的。当变量n1超出范围时,内存被释放。

在第二种情况下,内存是在堆上分配的。您必须显式释放内存资源(就像您正在做的那样free)。

经验法则可以是您将堆栈分配的内存用于大小有限的本地临时数据结构(堆栈只是计算机内存的一部分,因平台而异)。将堆用于要持久化或较大的数据结构。

谷歌搜索堆栈和堆将为您提供更多信息。

于 2013-10-10T06:38:26.997 回答
1

通常你只使用 malloc,如果你不知道在应用程序运行之前你需要的内存大小。

您的代码是正确的,但您不能动态分配内存。如果您想在 node.date 中保存一个测量值并且您不知道要捕获多少个测量值怎么办?然后你必须在你采取的每一个措施上分配一些新的内存。

如果您在运行时之前定义所有节点(直接在代码中),则无法保存比之前定义的更多的度量。

在 c 中搜索链表,你会发现一些很好的例子。

于 2013-10-10T06:52:50.523 回答
1

您的数据类型看起来像树中的一个节点。malloc用于树节点分配的两个主要原因是

  1. 分配任意数量的节点。树节点的数量通常是运行时值。由于这个原因,不可能为这些节点声明适当数量的局部变量,因为所有局部变量都必须在编译时声明。同时,malloc可以根据需要在运行时多次调用,根据需要分配尽可能多的节点对象。

  2. 确保在本地对象的生命周期结束时(即在块结束时)不会自动销毁节点。malloc由live forever分配的对象,即直到您通过调用显式销毁它们free。这样的对象将超越块边界和功能边界。本地对象不可能有这样的事情,因为本地对象在它们的块结束时会自动销毁。

您的代码示例不依赖于动态分配的任何好处,因为它并没有真正创建真正的树。它只是声明为单节点。但是,如果您尝试构建具有运行时节点数的完整树,您将立即意识到通过将节点声明为本地对象是不可能的。您将不可避免地必须使用malloc.

您的“未初始化为内存位置的 n1 如何能够存储数据”的问题一定是由一些混淆引起的。struct node n1;是一个对象定义,这意味着它为n1. 这正是对象定义的目的。

于 2013-10-10T06:57:16.657 回答