Home > Back-end >  I am using malloc() to allocate a pointer (8bytes) but it's able to store the whole node (16byt
I am using malloc() to allocate a pointer (8bytes) but it's able to store the whole node (16byt

Time:10-10

What I did :

I added a pointer in the parameter of malloc(struct Node *) which is usually malloc(struct Node).

Problem :

When I am allocating memory for the size of a pointer then how the code is working?

  • malloc() is allocating 8 bytes of memory and returning the pointer
  • So the pointer points to an 8 bytes memory block which but further I am storing more data in it.
struct Node
{
  int data;
  struct Node *next;
};

struct Node *GetNode(int data)
{
  struct Node *node = (struct Node *)malloc(sizeof(struct Node *));
  node->data = data;
  node->next = NULL;
  return node;
}

Difference in size:

I know that malloc is allocating different sizes because I did this

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

struct Node
{
  int data;
  struct Node *next;
};

void main(){
  int i = sizeof(struct Node);
  int j = sizeof(struct Node *);
  printf("%d,%d", i, j);
}

Output

16,8

CodePudding user response:

What you've done is undefined behavior. It could work (on some systems, on certain days of the week), or it could crash, or it could produce incorrect results in seemingly unrelated calculations.

Imagine you rent a garage space for your truck, but to save money you request a space for a car. What happens when you drive your truck in? Maybe it fits, maybe you wreck the truck, maybe you destroy the garage.

So don't do that, and to help you find cases where you've made similar mistakes, build with Address Sanitizer. It will log when you access memory in an invalid way.

CodePudding user response:

UB is a fickle mistress. Sometimes agreeable; sometimes not.

That is why you should use a syntax that makes it less likely to make mistakes:

struct Node *node = (struct Node *)malloc(sizeof(struct Node *)); // bad

struct Node *node = malloc( sizeof *node ); // good

No casting, and no redundancy.

I would even recommend using typedef's to free yourself from "struct, struct, struct".

typedef struct s_node
{
    int data;  // use more indentation, please. whitespace is cheap.
    struct s_node *next;
} Node_t;

/* ... */

Node_t *node = malloc( sizeof *node ); // better

Finally, a lot of hours are wasted tracking down bugs that appear and disappear. Until performance becomes a real issue that you understand, I'd recommend using calloc() as the go-to allocation function:

Node_t *node = calloc( 1, sizeof *node ); // best

You can sleep easier knowing the byte values will be repeatable from run to run.

  • Related