malloc 如何分配 24 字节以满足内存对齐,因为我们只是传递结构的大小(13 字节)?
它没有。如果 malloc(13) 恰好返回至少 24 个字节,则这是 malloc 实现的一个怪癖。 malloc 被允许分配比必要更多的空间,并且通常出于字节对齐和各种其他实现原因而必须分配。
我们可以通过一个简单的程序看到这一点。
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
从地址中我们可以看出,malloc(13) 返回的指针之间有 32 个字节。大量适合您的 24 个字节,并且程序“有效”。即使malloc(1) 返回相同的结果。
但是如果我们让你的结构更大一点...
struct st {
char c;
double b;
double a;
double d;
int i;
};
这是 40 个字节,对齐。现在它不适合 32 字节,我们看到损坏,因为结构的内存相互重叠。
#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 是 ascii b。 99 是 ascii c。 100 是 ascii d。这表示a->i 与b->c 重叠,b->i 与c->c 重叠,等等。