1

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
Areeb
  • 38
  • 2
  • 8
  • Does this answer your question? [Why does malloc(1) work for storing 4 byte integers?](https://stackoverflow.com/questions/41822904/why-does-malloc1-work-for-storing-4-byte-integers) – Nick ODell Oct 09 '22 at 15:30
  • sizeof(struct Node) represents the size of the Node structure while sizeof(struct Node *) represents the size of a variable that points to a Node structure (a struct Node pointer) – Razvan Oct 09 '22 at 15:30
  • Please explain to yourself, your roommate, friends or even just a [rubber duck](https://en.wikipedia.org/wiki/Rubber_duck_debugging) what the difference between `struct Node` and `struct Node *` is. – Some programmer dude Oct 09 '22 at 15:32
  • On another note, the correct format to print `size_t` values (and the result of the `sizeof` operator is a value of type `size_t`) is `%zu`. Mismatching format specifier and argument type leads to *undefined behavior*. – Some programmer dude Oct 09 '22 at 15:33
  • 1
    And you [really shouldn't be casting the result of `malloc`](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858). – Some programmer dude Oct 09 '22 at 15:34
  • 2
    In C, so many things are [undefined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior) that it is entirely possible for completely wrong code to appear to be "working". As a result, trying to learn about C purely by experimentation, by just trying random code and seeing if it "works", is not usually a good approach. – Nate Eldredge Oct 09 '22 at 15:37
  • 1
    "how the code is working?" [It doesn't](https://godbolt.org/z/W9rhzfvrn). – n. m. could be an AI Oct 09 '22 at 21:40
  • You do understand why sizeof(struct Node) and sizeof(struct Node *) are supposed to be different? When you use sizeof will malloc, you send the size of the thing pointed to, not the size of the pointer. As the others have said, if this works it's by accident. It may be that malloc has some minimum size of block that it actually allocates, and it's at least 16 btyes, so you happen to get enough. Not something to count on. – T W Bennet Oct 14 '22 at 22:33

2 Answers2

1

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.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
0

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.

Fe2O3
  • 6,077
  • 2
  • 4
  • 20