0

If there is a structure as below:

struct student {
    int id;
    int marks;
} *S1,S2;

Why is it required to allocate memory to *S1 but not to S2? When *S1 is declared as a structure pointer, is there no memory allocated to it? Is memory allocated only when we explicitly allocate?

Shahid
  • 2,288
  • 1
  • 14
  • 24
d.a
  • 7
  • 1
  • 3
  • 3
    Who said that anything was required? – Kerrek SB Aug 26 '16 at 17:18
  • 2
    Memory *is* automatically allocated for S1. Exactly enough memory to represent a pointer. You can point that anywhere you like, even unallocated memory, it will be a valid pointer pointing at an invalid `struct student`. – Tibrogargan Aug 26 '16 at 17:21
  • Memory for the pointer itself is allocated, but until you allocate a `student` and assign the pointer to point to the location of that memory, the pointer will be pointing to garbage if uninitialized. S2 is being allocated the same way the pointer S1 is; but one is a `student` and one is a pointer. The memory of the pointer itself and what it's pointing to are completely different things. – John Aug 26 '16 at 17:22
  • @Tibrogargan - That's not really a valid pointer... – Oliver Charlesworth Aug 26 '16 at 17:33
  • Yes memory is allocated to `*S1` only when you explicitly allocate. As opposed to `S2` which is an actual `struct`,not a pointer. – Weather Vane Aug 26 '16 at 17:37
  • @OliverCharlesworth It's valid for use as a pointer. Assigning a value to it won't cause an access violation, neither will reading the value. What it points to may not be valid. – Tibrogargan Aug 26 '16 at 17:45
  • @Tibrogargan - In theory, it's more complicated than that: http://stackoverflow.com/questions/17024866/when-is-it-valid-to-access-a-pointer-to-a-dead-object – Oliver Charlesworth Aug 26 '16 at 17:47
  • @OliverCharlesworth you're implying there is no determinate way to test if a pointer is null, since if the pointer's value has become indeterminate simply reading the pointer invokes undefined behavior – Tibrogargan Aug 26 '16 at 18:09
  • @tibrogargan: don't have the spec to hand right now, but I would wager that null is defined not to be an indeterminate/trap representation. – Oliver Charlesworth Aug 26 '16 at 18:24
  • @OliverCharlesworth Schrodinger's pointer. You don't know if it's null until after you read it. It's still undefined behavior – Tibrogargan Aug 26 '16 at 18:26
  • @tibrogargan: if there's a chance it's indeterminate (as opposed to null or pointing to a valid object) then you shouldn't be reading it. I'm not sure what use case there'd be for that, either. – Oliver Charlesworth Aug 26 '16 at 18:27
  • @OliverCharlesworth That's exactly my point. You are implying that there is literally no determinate way to test if a pointer is null. – Tibrogargan Aug 26 '16 at 18:29
  • @tibrogargan: only when "indeterminate" is one other possible value. You shouldn't write code where that's a possibility. – Oliver Charlesworth Aug 26 '16 at 18:31
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/121963/discussion-between-tibrogargan-and-oliver-charlesworth). – Tibrogargan Aug 26 '16 at 18:31

3 Answers3

3

In C, each variable is a memory location. In your example, both S1 and S2 are variables, but, S1 happens to be a pointer. A pointer is a variable which by purpose is defined to hold the address of a memory location.

In your example S2 being a normal variable of type struct student points to a memory location whose size is sizeof(struct student). S1 being a pointer variable points to a memory location whose size is equivalent to the size of a pointer variable (4 bytes for 32 bit systems and 8 bytes for 64 bit systems typically).

Just as you need to assign values to normal variables, you need to assign the address of a memory location to a pointer which is what you do when you allocate a memory and assign to it.

Jay
  • 24,173
  • 25
  • 93
  • 141
2

Well, it is how the language work. It automatically reserves memory for the type you ask for. If you ask for a struct student, it reserves memory for a struct student. If you ask for a pointer, it reserves memory for a pointer.

Example with int:

int n;  // Reserves memory for an int
int *p; // Reserves memory for a pointer (that points to an int)
        // but there is no memory allocated to hold the int
        // p needs to be initialized before you dereference it (i.e. *p)

p = malloc(sizeof(int));  // Initialize p and allocate memory to hold the int
if (!p) exit(1);          // Error - no memory available

*p = 5; // Now p can be used

free(p); // Release the memory

Your case is not different than the example above. S2 is a struct student while S1 is a pointer (to a struct student) and you need to initialize S1 by allocating memory for a struct student. Like:

S1 = malloc(sizeof(struct student));
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
0

Each variable is associated with some storage (at least in C). So it is for S1 and S2. But S1 is a pointer, so storage for pointer to structure is required, S2 is a structure so storage for a full structure is allocated. What makes the difference is that S1 is an indirection, means that its storage does not contains a structure but address of a structure, if you want it to be linked to a structure you need to provide it an appropriate address. Either:

S1 = &S2;

where & is the operator that take the address of S2. Now S1 is a link to S2. Or:

S1 = malloc(sizeof(struct student));

where malloc (dynamically) allocates a storage for a structure and returns its address (in case of success).

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69