When and why to use malloc
Asked Answered
A

6

98

Well, I can't understand when and why it is needed to allocate memory using malloc.

Here is my code:

#include <stdlib.h>

int main(int argc, const char *argv[]) {

  typedef struct {
    char *name;
    char *sex;
    int age;
  } student;


  // Now I can do two things
  student p;

  // Or
  student *ptr = (student *)malloc(sizeof(student));

  return 0;
}

Why is it needed to allocate memory when I can just use student p;?

Anderaanderea answered 10/1, 2012 at 8:40 Comment(2)
You must learn about the differences between heap and stack memory, take a look at this question: #80423Crocker
Don't forget to call free after malloc/calloc etc...Outshine
M
98

malloc is used for dynamic memory allocation. As said, it is dynamic allocation which means you allocate the memory at run time. For example, when you don't know the amount of memory during compile time.

One example should clear this. Say you know there will be maximum 20 students. So you can create an array with static 20 elements. Your array will be able to hold maximum 20 students. But what if you don't know the number of students? Say the first input is the number of students. It could be 10, 20, 50 or whatever else. Now you will take input n = the number of students at run time and allocate that much memory dynamically using malloc.

This is just one example. There are many situations like this where dynamic allocation is needed.

Have a look at the man page malloc(3).

Mathewson answered 10/1, 2012 at 8:46 Comment(4)
Just because it's unknown how much memory is needed at compile time, doesn't mean the heap has to be involved.Sismondi
@Matt Joiner, that was ONE example. If you think that is worth of downvoting then I have nothing to say.Mathewson
@Matt Joiner, edited the answer a little bit. May be it sounds better now.Mathewson
This answer fails to mention the very important use of malloc to allocate memory with a lifetime beyond that of execution of the current block.Sisco
V
54

You use malloc when you need to allocate objects that must exist beyond the lifetime of execution of the current block (where a copy-on-return would be expensive as well), or if you need to allocate memory greater than the size of that stack (i.e., a 3 MB local stack array is a bad idea).

Before C99 introduced VLAs, you also needed it to perform allocation of a dynamically-sized array. However, it is needed for creation of dynamic data structures like trees, lists, and queues, which are used by many systems. There are probably many more reasons; these are just a few.

Vinic answered 10/1, 2012 at 8:45 Comment(3)
lexical scope and storage duration are two different things. An object can have block scope and static storage duration.Candlestand
@ouah: then it wouldn't be a stack allocated object, which is what I'm referring to.Vinic
Before C99 you could use alloca. That aside, this is the most correct answer, and should be marked the solution.Sismondi
M
22

Expanding the structure of the example a little, consider this:

#include <stdio.h>

int main(int argc, const char *argv[]) {

    typedef struct {
        char *name;
        char *sex;
        char *insurance;
        int age;
        int yearInSchool;
        float tuitionDue;
    } student;

    // Now I can do two things
    student p;

    // Or
    student *p = malloc(sizeof *p);
}

C is a language that implicitly passes by value, rather than by reference. In this example, if we passed 'p' to a function to do some work on it, we would be creating a copy of the entire structure. This uses additional memory (the total of how much space that particular structure would require), is slower, and potentially does not scale well (more on this in a minute). However, by passing *p, we don't pass the entire structure. We only are passing an address in memory that refers to this structure. The amount of data passed is smaller (size of a pointer), and therefore the operation is faster.

Now, knowing this, imagine a program (like a student information system) which will have to create and manage a set of records in the thousands, or even tens of thousands. If you pass the whole structure by value, it will take longer to operate on a set of data, than it would just passing a pointer to each record.

Motoneuron answered 28/11, 2012 at 0:7 Comment(1)
Can't you just pass a pointer to a function using &p and still avoid using malloc?Brey
P
13

Let's try and tackle this question considering different aspects.

Size

malloc allows you to allocate much larger memory spaces than the one allocated simply using student p; or int x[n];. The reason being malloc allocates the space on heap while the other allocates it on the stack.

The C programming language manages memory statically, automatically, or dynamically. Static-duration variables are allocated in main memory, usually along with the executable code of the program, and persist for the lifetime of the program; automatic-duration variables are allocated on the stack and come and go as functions are called and return. For static-duration and automatic-duration variables, the size of the allocation must be compile-time constant (except for the case of variable-length automatic arrays[5]). If the required size is not known until run-time (for example, if data of arbitrary size is being read from the user or from a disk file), then using fixed-size data objects is inadequate. (from Wikipedia)

Scope

Normally, the declared variables would get deleted/freed-up after the block in which it is declared (they are declared on the stack). On the other hand, variables with memory allocated using malloc remain till the time they are manually freed up.

This also means that it is not possible for you to create a variable/array/structure in a function and return its address (as the memory that it is pointing to, might get freed up). The compiler also tries to warn you about this by giving the warning:

Warning - address of stack memory associated with local variable 'matches' returned

For more details, read this.

Changing the Size (realloc)

As you may have guessed, it is not possible by the normal way.

Error detection

In case memory cannot be allocated: the normal way might cause your program to terminate while malloc will return a NULL which can easily be caught and handled within your program.

Making a change to string content in future

If you create store a string like char *some_memory = "Hello World"; you cannot do some_memory[0] = 'h'; as it is stored as string constant and the memory it is stored in, is read-only. If you use malloc instead, you can change the contents later on. For more information, check this answer.

For more details related to variable-sized arrays, have a look at this.

Parse answered 30/12, 2018 at 16:44 Comment(2)
What is "the normal way"? You should be more specific here. For instance, you can't resize a static or local variable.Mendes
How do you call that variable from another scope if it doesn't exist in that scope anymore?Logogram
A
6

malloc = Memory ALLOCation.

If you been through other programming languages, you might have used the new keyword.

Malloc does exactly the same thing in C. It takes a parameter, what size of memory needs to be allocated and it returns a pointer variable that points to the first memory block of the entire memory block, that you have created in the memory. Example -

int *p = malloc(sizeof(*p)*10);

Now, *p will point to the first block of the consecutive 10 integer blocks reserved in memory.

You can traverse through each block using the ++ and -- operator.

Alithia answered 10/1, 2012 at 8:47 Comment(1)
you mean consecutive 10 integer block?Affusion
T
-2

In this example, it seems quite useless indeed.

But now imagine that you are using sockets or file I/O and must read packets from variable length which you can only determine while running. Or when using sockets and each client connection need some storage on the server. You could make a static array, but this gives you a client limit which will be determined while compiling.

Thesda answered 10/1, 2012 at 8:48 Comment(1)
Variable length arrays can be stored on the stack just fine. Variable length arrays are no reason to use the heap.Sismondi

© 2022 - 2024 — McMap. All rights reserved.