C中的malloc()有哪些有用的例子?

时间:2010-11-03 07:28:04

标签: c malloc

我只是在C中阅读malloc()

Wikipedia article提供example,但与int array[10]相比,它只为10个整数的数组分配了足够的内存。不太有用。

您何时决定使用malloc()而不是C为您处理内存?

6 个答案:

答案 0 :(得分:19)

动态数据结构(列表,树等)使用malloc在堆上分配节点。例如:

/* A singly-linked list node, holding data and pointer to next node */
struct slnode_t
{
    struct slnode_t* next;
    int data;
};

typedef struct slnode_t slnode;

/* Allocate a new node with the given data and next pointer */
slnode* sl_new_node(int data, slnode* next)
{
    slnode* node = malloc(sizeof *node);
    node->data = data;
    node->next = next;
    return node;
}

/* Insert the given data at the front of the list specified by a 
** pointer to the head node
*/
void sl_insert_front(slnode** head, int data)
{
    slnode* node = sl_new_node(data, *head);
    *head = node;
}

考虑如何使用sl_insert_front将新数据添加到列表中。您需要创建一个节点来保存数据和指向列表中下一个节点的指针。你打算在哪里创造它?

  • 也许在堆栈上! - - 将分配堆栈空间的位置?在哪个功能?当函数退出时会发生什么?
  • 也许在静态记忆中! - - 您必须提前知道您有多少列表节点,因为在程序加载时预先分配了静态内存。
  • 在堆上? - 因为您拥有所有必需的灵活性。
在C中使用

malloc来分配堆上的东西 - 可以在运行时动态增长和缩小的内存空间,其所有权完全由程序员控制。还有更多的例子,这是有用的,但我在这里展示的是一个代表性的例子。最终,在复杂的C程序中,您会发现程序的大部分数据都在堆上,可通过指针访问。正确的程序总是知道哪个指针“拥有”数据,并在不再需要时仔细清理已分配的内存。

答案 1 :(得分:4)

如果在编写程序时不知道数组的大小,该怎么办? 举个例子,我们可以想象你想要加载一个图像。首先你不知道它的大小,所以你必须从文件中读取大小,分配一个具有这个大小的缓冲区,然后读取该缓冲区中的文件。显然你不能使用静态大小数组。

编辑:

另一点是:当您使用动态分配时,将在堆上分配内存,而在堆上分配数组。当您在嵌入式设备上进行编程时,这非常重要,因为与堆相比,堆栈的大小可能有限。

答案 2 :(得分:2)

在您离开堆叠框架时,您所描述的示例int array[10]消失了。如果您希望使用的内存超出本地范围,则必须使用malloc();

答案 3 :(得分:2)

我建议你google Stack and Heap

int* heapArray = (int*)malloc(10 * sizeof(int));
int stackArray[10];

两者在访问数据的方式上非常相似。它们在幕后存储数据的方式上有很大不同。 heapArray在堆上分配,仅在应用程序终止或调用free(heapArray)时才被解除分配。 stackArray在堆栈上分配,并在堆栈展开时释放。

答案 4 :(得分:1)

无论何时使用

malloc():

  1. 您需要动态内存分配 如果你需要创建大小为n的数组,其中n是在程序执行期间计算的,唯一的方法就是使用malloc()。

  2. 您需要在堆中分配内存 某些函数中定义的变量仅在此函数结束时生效。因此,如果需要一些“独立于callstack”的数据,它必须作为函数参数传递/返回(这并不总是合适的),或者存储在堆中。在堆中存储数据的唯一方法是使用malloc()。有可变大小的数组,但它们是在堆栈上分配的。

答案 5 :(得分:1)

尽管从C99开始可以使用可变长度数组,但仍然没有更好的替代动态数据结构。典型的例子是链表。要获得任意大小,可以使用malloc分配每个节点,这样就可以插入和删除而无需大量内存复制,就像可变长度数组一样。

例如,使用简单链表的任意大小的堆栈:

#include <stdio.h>
#include <stdlib.h>

typedef struct sNode {
    int payLoad;
    struct sNode *next;
} tNode;

void stkPush (tNode **stk, int val) {
    tNode *newNode = malloc (sizeof (tNode));
    if (newNode == NULL) return;
    newNode->payLoad = val;
    newNode->next = *stk;
    *stk = newNode;
}

int stkPop (tNode **stk) {
    tNode *oldNode;
    int val;
    if (*stk == NULL) return 0;
    oldNode = *stk;
    *stk = oldNode->next;
    val = oldNode->payLoad;
    free (oldNode);
    return val;
}

int main (void) {
    tNode *top = NULL;
    stkPush (&top, 42);
    printf ("%d\n", stkPop (&top));
    return 0;
}

现在,可能使用可变长度数组执行此操作,但是,就像在COBOL中编写操作系统一样,有更好的方法可以做到这一点。