win10 x64, 指针大小是8个字节
1 分析一下链表的内存结构
#include <stdlib.h>
typedef struct node
{
int key;
int data;
struct node *next;
} Node;
Node *head = NULL;
Node *nodes = NULL;
Node *create_list(int n)
{
int i;
// allocate memory for all nodes
nodes = malloc(n * sizeof(Node));
printf(" sizeof(Node) = %d\n", sizeof(Node));
if (nodes == NULL) {
return NULL;
}
// link the nodes together
head = &nodes[0];
for (i = 0; i < n-1; i++) {
nodes[i].next = &nodes[i+1];
}
nodes[n-1].next = NULL;
return head;
}
void main() {
Node *n1 = create_list(3);
n1->key = 1;
//n1->data = 11;
Node *n2 = n1->next;
n2->key = 2;
printf(" n1 = %p \n", n1);
printf(" n1->key = %p \n", &n1->key);
printf(" n1->data = %p \n", &n1->data);
printf(" n1+1 = %p \n", n1+1);
printf(" n1+2 = %p \n", n1+2);
printf(" n1->next = %p \n", n1->next);
printf(" n2 = %p \n", n2);
printf(" n2->key = %p \n", &n2->key);
printf(" n2->data = %p \n", &n2->data);
Node *n3 = n2->next;
n3->key = 3;
printf(" n3 = %p \n", n3);
}
输出1:
sizeof(Node) = 16
n1 = 0000000000AB2400
n1->key = 0000000000AB2400
n1->data = 0000000000AB2404
n1+1 = 0000000000AB2410 // 对应下图中的 n+1 与 n2的地址相同
n1+2 = 0000000000AB2420 // 对应下图中的 n+2 与 n3的地址相同
n1->next = 0000000000AB2410 与 n2的地址相同
n2 = 0000000000AB2410
n2->key = 0000000000AB2410
n2->data = 0000000000AB2414
n3 = 0000000000AB2420
根据上面的输出结果可以分析出下图的内存结构
2 换种方式,修改一下Node
typedef struct node
{
int key; //4
// int key2; //4 这里要不要key2 Node的大小都是56,因为字节对齐的原因
int data[10]; //40
struct node *next; //8
} Node;
输出2:
sizeof(Node) = 56
n1 = 00000000001D5FD0
n1->key = 00000000001D5FD0 // 这里加4 <=> &n1->data
n1->data = 00000000001D5FD4 D6008 - D5FD4 = 34 ====> 52 = 40(data) + 8(next) + 4(4字节空位,内存对齐,参考输出3,就没有突然冒出个4的烦恼了,而且这里的4字节占位是放在data后面)
n1+1 = 00000000001D6008 与 n2的地址相同
n1+2 = 00000000001D6040 与 n3的地址相同
n1->next = 00000000001D6008 与 n2的地址相同
n2 = 00000000001D6008
n2->key = 00000000001D6008
n2->data = 00000000001D600C
n3 = 00000000001D6040
3 注释掉的int key2; 恢复
typedef struct node
{
int key; //4
int key2; //4 这里要不要key2 Node的大小都是56,因为字节对齐的原因
int data[10]; //40
struct node *next; //8
} Node;
输出3:
sizeof(Node) = 56
n1 = 0000000000965FD0
n1->key = 0000000000965FD0
n1->data = 0000000000965FD8 // 6008 - 5FD8 = 30 ====> 48
n1+1 = 0000000000966008
n1+2 = 0000000000966040
n1->next = 0000000000966008
n2 = 0000000000966008
n2->key = 0000000000966008
n2->data = 0000000000966010
n3 = 0000000000966040
分析可得:红色的4是内存对齐,占位的部分
这样就可以更好的理解 nodes = malloc(n * sizeof(Node)); 这段分配内存代码的内涵了