考虑一下我的结构如下。
struct st
{
char c;
double d;
int i;
};
根据struct st
的内存对齐大小将为(1 + 7(已填充)+ 8 + 4 + 4(已填充))= 24字节
当我按如下所述进行malloc
时
struct st *p = malloc(sizeof(*p));
它将与
相同struct st *p = malloc(13);
由于我们只是传递结构的大小(13bytes),因此malloc如何分配24个字节以满足内存对齐?
答案 0 :(得分:4)
这个问题错误地认为
struct st *p = malloc(sizeof(*p));
与
相同struct st *p = malloc(13);
不是。要测试,
printf ("Size of st is %d\n", sizeof (*p));
打印24
,而不是13。
分配和管理结构的正确方法是使用sizeof(X)
,而不是假设元素是如何打包或对齐的。
答案 1 :(得分:0)
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
重叠,依此类推。