使用 malloc 的结构数据对齐
Data alignment of structure using malloc
考虑我的结构如下。
struct st
{
char c;
double d;
int i;
};
根据 struct st
的内存对齐大小将为 (1+7(padded)+8+4+4(padded))=24bytes
当我malloc
如下
struct st *p = malloc(sizeof(*p));
它将与
相同
struct st *p = malloc(13);
malloc 如何分配 24 字节以满足内存对齐,因为我们只是传递结构的大小(13 字节)?
How does malloc
allocate 24 bytes to meet memory alignment since we are just passing the size of structure (13 bytes)?
没有。如果 malloc(13)
碰巧 return 至少 24 个字节,这是 malloc
实现的一个怪癖。 malloc
被允许分配比必要更多的 space,并且通常出于字节对齐和其他各种实现原因必须分配。
我们可以通过一个简单的程序看到这一点。
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)
编辑的指针return之间有32个字节。足以容纳您的 24 字节和程序 "works"。即使 malloc(1)
return 结果相同。
但是如果我们让你的结构稍微大一点...
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
重叠,依此类推。
该问题错误地假设
struct st *p = malloc(sizeof(*p));
与
相同
struct st *p = malloc(13);
不是。测试,
printf ("Size of st is %d\n", sizeof (*p));
打印 24
,而不是 13.
分配和管理结构的正确方法是使用 sizeof(X)
,而不是假设元素是如何打包或对齐的。
考虑我的结构如下。
struct st
{
char c;
double d;
int i;
};
根据 struct st
的内存对齐大小将为 (1+7(padded)+8+4+4(padded))=24bytes
当我malloc
如下
struct st *p = malloc(sizeof(*p));
它将与
相同struct st *p = malloc(13);
malloc 如何分配 24 字节以满足内存对齐,因为我们只是传递结构的大小(13 字节)?
How does
malloc
allocate 24 bytes to meet memory alignment since we are just passing the size of structure (13 bytes)?
没有。如果 malloc(13)
碰巧 return 至少 24 个字节,这是 malloc
实现的一个怪癖。 malloc
被允许分配比必要更多的 space,并且通常出于字节对齐和其他各种实现原因必须分配。
我们可以通过一个简单的程序看到这一点。
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)
编辑的指针return之间有32个字节。足以容纳您的 24 字节和程序 "works"。即使 malloc(1)
return 结果相同。
但是如果我们让你的结构稍微大一点...
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
重叠,依此类推。
该问题错误地假设
struct st *p = malloc(sizeof(*p));
与
相同struct st *p = malloc(13);
不是。测试,
printf ("Size of st is %d\n", sizeof (*p));
打印 24
,而不是 13.
分配和管理结构的正确方法是使用 sizeof(X)
,而不是假设元素是如何打包或对齐的。