Динамические структуры данных (списки, деревья и т. Д.) Используют 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
. Вам необходимо создать узел, который будет содержать данные и указатель на следующий узел в списке. Где вы собираетесь его создать?
- Может быть, в стеке! - NO - где будет выделено это пространство стека? В какой функции? Что происходит с ним при выходе из функции?
- Может быть, в статической памяти! - NO - вам нужно будет заранее знать, сколько узлов списка у вас есть, поскольку статическая память предварительно выделяется при загрузке программы.
- В куче? ДА - потому что там у вас есть вся необходимая гибкость.
malloc
используется в C для выделения содержимого в куче - пространстве памяти, которое может динамически увеличиваться и уменьшаться во время выполнения, и владение которым полностью находится под контролем программиста. Есть еще много примеров, где это полезно, но пример, который я показываю здесь, является типичным. В конце концов, в сложных программах на С вы обнаружите, что большая часть данных программы находится в куче, доступной через указатели. Правильная программа всегда знает, какой указатель «владеет» данными, и будет тщательно очищать выделенную память, когда она больше не нужна.