#include <stdio.h>
#include <malloc.h>
typedef struct Node {
int value; //4
struct Node* next; //4
}Node;
Node *create();
void add();
void del();
void search();
Node *create(int v) {
Node *first;
first = (Node *)(calloc(1,sizeof(*first)));
first->value = v;
first->next = NULL;
return first;
}
void add(Node **head,int v) {
Node *p;
p = (Node *)(calloc(1,sizeof(*p)));
p->value = v;
p->next = *head;
*head = p;
}
void search(Node *head) {
Node *p;
p=head;
while(p != NULL) {
printf("address is %d;value address is %d;next address is %d;next content is %d\n",p,&(p->value),&(p->next),p->next);
p = p->next;
}
}
int main() {
Node *head;
head = create(0);
add(&head,1);
add(&head,2);
add(&head,3);
search(head);
}
sizeof(Node) == 8
,但为什么堆中每个节点的大小都是16个字节?想
(我的系统是32位)。
struct node是4bytes + 4bytes = 8bytes。
答案 0 :(得分:2)
节点大小不是16个字节,只是malloc()
选择跳过8个字节的内存由于某种原因,可能是它自己的簿记。如果你想节省内存,做一些大的分配,而不是很少的小分配,否则簿记费用可能会花费很多。
答案 1 :(得分:1)
好吧,即使在calloc()
的来电之间分配的内存对你的程序来说是连续的(你无法确定),也不要忘记lib c有私有的&#39;存储在您分配的内存块中的数据。
通常会有一个标题:
struct hdr
{
size_t size; /* Exact size requested by user. */
unsigned long int magic; /* Magic number to check header integrity. */
struct hdr *prev;
struct hdr *next;
__ptr_t block; /* Real block allocated, for memalign. */
unsigned long int magic2; /* Extra, keeps us doubleword aligned. */
};
您可能会看到该块实际上是您在调用malloc()
/ calloc()
时获得的数据缓冲区,其中包含大量额外数据( ok,这里是调试的特例,因此可能有额外的魔法)。
答案 2 :(得分:0)
代码中涉及的错误是与各种列表函数相关的逻辑错误。当您具有add
函数时,该函数的作用是为节点分配内存并分配所需的任何值。它不担心它正在处理哪个节点。
相反,你的create
函数没有分配任何东西,它只是调用add
来处理那项工作,然后它的工作只是正确地连接指针和next-&gt;指向正确节点的指针。 / p>
由于您正在处理包含数据的头节点,因此head
有3种可能的条件; (1)当NULL
为head->next
时; (2)当NULL
为#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int value; //4
struct Node* next; //4
} Node;
/* function prototypes */
Node *create (int v);
void add (Node **head, int v);
void del ();
void search (Node *head);
void printvalues (Node *head);
int main (void) {
Node *head = NULL;
// head = create(0);
add (&head,0);
add (&head,1);
add (&head,2);
add (&head,3);
printf ("\nsearching:\n\n");
search (head);
printf ("\nprinting:\n\n");
printvalues (head);
return 0;
}
/* create - only creates nodes */
Node *create (int v)
{
Node *new;
new = calloc (1, sizeof *new);
new->value = v;
new->next = NULL;
return new;
}
/* add does NOT create - only handles wiring */
void add (Node **head, int v)
{
Node *new = create (v);
if (!*head) {
*head = new;
return;
}
Node *p = *head;
while (p && p->next)
p = p->next;
if (!(*head)->next)
(*head)->next = new;
else
p->next = new;
}
void search(Node *head)
{
Node *p = head;
while (p != NULL) {
printf (" address is %p; next address is %p;\n", p, p->next);
p = p->next;
}
}
void printvalues (Node *head)
{
Node *p = head;
unsigned cnt = 0;
while (p != NULL) {
printf (" node[%2u] value: %d\n", cnt++, p->value);
p = p->next;
}
}
时; (3)所有剩余的补充。
将这些部分组合在一起并添加打印功能,您的代码可能如下所示:
$ ./bin/dbgllmess
searching:
address is 0x1acf010; next address is 0x1acf030;
address is 0x1acf030; next address is 0x1acf050;
address is 0x1acf050; next address is 0x1acf070;
address is 0x1acf070; next address is (nil);
printing:
node[ 0] value: 0
node[ 1] value: 1
node[ 2] value: 2
node[ 3] value: 3
<强>输出强>
{{1}}
注意:您负责释放不再需要的内存。如果您有任何问题,请告诉我。
答案 3 :(得分:0)
关于真正的问题“为什么堆中每个节点的大小都是16个字节?”
好吧,你不能指望一个内存块正好位于前一个内存块所在的末尾。你不能假设任何关于堆如何被密切管理的事情。即使用malloc
全部涂层,两块也可以相互保持千兆字节的距离。
在Windows上,为了使堆能够跟踪分配的内存块,每个块都会获得更多的字节来保存内存块的元数据。这被称为“堆条目”,这可能是你的块更大的原因。
但同样,你不能假设任何块 - 无论如何都要在堆中定位。