What are some useful examples of malloc() in C?

33,091

Solution 1

Dynamic data structures (lists, trees, etc.) use malloc to allocate their nodes on the heap. For example:

/* 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;
}

Consider how new data is added to the list with sl_insert_front. You need to create a node that will hold the data and the pointer to the next node in the list. Where are you going to create it?

  • Maybe on the stack! - NO - where will that stack space be allocated? In which function? What happens to it when the function exits?
  • Maybe in static memory! - NO - you'll then have to know in advance how many list nodes you have because static memory is pre-allocated when the program loads.
  • On the heap? YES - because there you have all the required flexibility.

malloc is used in C to allocate stuff on the heap - memory space that can grow and shrink dynamically at runtime, and the ownership of which is completely under the programmer's control. There are many more examples where this is useful, but the one I'm showing here is a representative one. Eventually, in complex C programs you'll find that most of the program's data is on the heap, accessible through pointers. A correct program always knows which pointer "owns" the data and will carefully clean-up the allocated memory when it's no longer needed.

Solution 2

What if you don't know the size of the array when you write your program ? As an example, we could imagine you want to load an image. At first you don't know its size, so you will have to read the size from the file, allocate a buffer with this size and then read the file in that buffer. Obviously you could not have use a static size array.

EDIT:

Another point is: When you use dynamic allocation, memory is allocated on the heap while arrays are allocated on the stack. This is quite important when you are programming on embedded device as stack can have a limited size compared to heap.

Solution 3

In the example you described int array[10] goes away when you leave your stack frame. If you would like the used memory to persist beyond local scope you have to use malloc();

Solution 4

I recommend that you google Stack and Heap.

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

Both are very similar in the way you access the data. They are very different in the way that the data is stored behind the scenes. The heapArray is allocated on the heap and is only deallocted when the application dies, or when free(heapArray) is called. The stackArray is allocated on the stack and is deallocated when the stack unwinds.

Solution 5

Although you can do variable length arrays as of C99, there's still no decent substitute for the more dynamic data structures. A classic example is the linked list. To get an arbitrary size, you use malloc to allocate each node so that you can insert and delete without massive memory copying, as would be the case with a variable length array.

For example, an arbitrarily sized stack using a simple linked list:

#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;
}

Now, it's possible to do this with variable length arrays but, like writing an operating system in COBOL, there are better ways to do it.

Share:
33,091
user3167101
Author by

user3167101

I like to make stuff. Check out my blog. You can email me at alex at my domain. My dotfiles, if you're curious :)

Updated on January 30, 2020

Comments

  • user3167101
    user3167101 over 4 years

    I'm just reading about malloc() in C.

    The Wikipedia article provides an example, however it justs allocate enough memory for an array of 10 ints in comparison with int array[10]. Not very useful.

    When would you decided to use malloc() over C handling the memory for you?