How does malloc allocate 24 bytes to meet memory alignment since we are just passing the size of structure (13 bytes)?
It doesn't. If malloc(13) happens to return at least 24 bytes it's a quirk of the malloc implementation. malloc is allowed to allocate more space than necessary and often must for byte alignment and various other implementation reasons.
We can see this with a simple program.
struct st *a = malloc(13);
struct st *b = malloc(13);
struct st *c = malloc(13);
struct st *d = malloc(13);
printf("%p\n%p\n%p\n%p\n", a, b, c, d);
0x602000003210
0x602000003230
0x602000003250
0x602000003270
As we can see from the addresses, the pointers returned by malloc(13) have 32 bytes between them. Plenty to fit your 24 bytes and the program "works". Even malloc(1) returns the same result.
But if we make your struct a little bigger...
struct st {
char c;
double b;
double a;
double d;
int i;
};
That's 40 bytes, aligned. Now it doesn't fit into 32 bytes and we see corruption because the struct's memory overlap with each other.
#include <stdlib.h>
#include <stdio.h>
struct st {
char c;
double b;
double a;
double d;
int i;
};
void print_struct(struct st* st) {
printf("%c %lf %d\n", st->c, st->d, st->i);
}
int main() {
const size_t struct_size = sizeof(char) + (sizeof(double) * 3) + sizeof(int);
printf("sizeof(struct st): %zu\n", sizeof(struct st));
printf("sizeof fields added together: %zu\n", struct_size);
struct st *a = malloc(13);
struct st *b = malloc(13);
struct st *c = malloc(13);
struct st *d = malloc(13);
printf("%p\n%p\n%p\n%p\n", a, b, c, d);
a->c = 'a';
a->d = 1.0;
a->i = 1;
b->c = 'b';
b->d = 2.0;
b->i = 2;
c->c = 'c';
c->d = 3.0;
c->i = 3;
d->c = 'd';
d->d = 4.0;
d->i = 4;
print_struct(a);
print_struct(b);
print_struct(c);
print_struct(d);
}
sizeof(struct st): 40
sizeof fields added together: 29
0x602000003210
0x602000003230
0x602000003250
0x602000003270
a 1.000000 98
b 2.000000 99
c 3.000000 100
d 4.000000 4
98 is ascii b. 99 is ascii c. 100 is ascii d. This indicates that a->i overlaps with b->c, b->i overlaps with c->c, and so on.
malloc(13)does allocate 24 bytes?13bytes, but some systems allocate more than you asked for because they deal with memory in minimum sized chunks. Don't rely on this.doubleonly requires 4 byte alignment, in which case yoursizeofis incorrect.sizeof(struct st)is24and consequentlysizeof(*p), so I don't know why you would evenmalloc(13)since you already know that24bytes are needed.