0

I searched and found Luke's very detailed reply to a similar question, however, my question (and confusion) still remain.

I don't understand why we can malloc a pointer to a struct, and this also malloc's the space for the contents of the struct.

For a standard node struct:

typedef struct node
{
    int n;
    struct node* next;
}
node;

Why does:

node* new_node = malloc(sizeof(node));

allow us to subsequently do:

new_node->n = 5;

without having to malloc space for the int inside of the struct?

I read this:

node* new_node = malloc(sizeof(node));

as //create a pointer to a struct type of node called new_node and allocate space for the pointer. Is this also creating the new_node and allocating space for the struct and its contents as well?

If I try to simplify in my mind, avoiding the struct component and say do this:

//create a pointer to an int and allocate space FOR THE POINTER

int* n = malloc(sizeof(int)):

if I want to actually store a number inside of the int that I'm pointing to, wouldn't I first have to allocate space for the int as well?

int n = 5;

At the end of the day, I just don't seem to understand when you do and don't have to malloc space for things when it deals with structs and their elements.

1

Consider this

typedef struct node
{
     int n;
     struct node* next;
} node;

Now when you say node *something, then it means that you declared a pointer that is meant to point to an object of type node, and stop there, nothing more. Now the question arises that where does it point to (or in general way, we can ask which memory location)? Since there is no memory location associated with something, hence using something(address where node* something points) can be dangerous. We haven't mentioned any code that says that something has pointed somewhere.

This can be typically done in two ways :

  1. Either you provide empty blocks of memory to it.
  2. Or you can serve it with object's address.

Both of the above things are one and the same, but just doing them in different ways.


Now, the question comes that what is malloc()? malloc() is some magic function which provides the demanded amount of memory. One parameter is passed through this function, that specifies the required amount of memory. This is done by returning a pointer to the reserved memory that malloc(size) brought for you. And this is why you write

node* new_node = malloc(sizeof(node));

to make new_node to point the memory gifted by malloc(). If somehow malloc() doesn't find a memory for you, it returns NULL. It should be noted that the memory block to which new_node is pointing, is still empty. So *new_node( which is supposed to hold the value stored on the memory block to which it is pointing) does not make any sense, however new_node is fine as it contains address of any memory block.


The another way of making a pointer to point a memory is by doing such a thing.

node* new_node;
node n;
// initialize n
new_node = &n;

In this way, we asked the pointer new_node to point to the address of variable n. Now since we have already initialized n, then there is no problem accessing *new_node or new_node.


Answering

Why does:

node* new_node = malloc(sizeof(node));

allow us to subsequently do:

new_node->n = 5;

without having to malloc space for the int inside of the struct?

Consider creating a new user defined datatype

struct another_datatype
{
     type1 var1;
     type2 var2;
     type3 var3;
     .
     .
     .
     typen varn;
};
struct my_datatype
{
      another_datatype var_name;
      my_datatype* next;
};

where another_datatype is any user defined datatype with several variables of same/different types. Also consider a pointer my_datatype* p. If we use malloc(sizeof(my_datatype)) to gift a memory block to p, Then this will create exactly enough room that can hold the data contained in var_name( + the pointing information). In other words, we have got memory allocated for all objects of another_datatype. And therefore we can work on them, change or assign them values.

if I want to actually store a number inside of the int that I'm pointing to, wouldn't I first have to allocate space for the int as well?

No(strictly speaking in this case only as this question is conveying a second meaning and unfortunately the answer of another one is yes), you need not allocate memory separately for var1, var2, var3... you can work with them directly as you have allocated memory for whole object that contains these objects.

Further Reading :

1
  • Thank you! Your explanation of how malloc works was the missing piece for me.
    – lethaljd
    Aug 26 '14 at 17:16
1

By declaring a node to be composed of an integer and a pointer to another node, and malloc'ing it, the compiler knows to allocate space for both an integer (4 bytes depending on your system) and a pointer (4 or 8 bytes depending on your system), so no need to malloc another 4 bytes for the integer all over again.

1
  • so even just declaring a pointer to a node is enough to make C know to malloc the pointer to the node, and the node struct itself?
    – lethaljd
    Aug 26 '14 at 15:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .