gpt4 book ai didi

c - 堆内存 : Gap of 16 bytes for 8 byte struct

转载 作者:太空宇宙 更新时间:2023-11-04 00:37:41 24 4
gpt4 key购买 nike

我正在使用以下代码创建一个新节点并将其插入到链表中,随后释放它们。

// the node
struct node
{
int data;
struct node *next;
};


// returns a pointer to a new node with data
struct node *new_node(int data)
{
struct node *node;
node = malloc(sizeof(struct node));
node->data = data;
node->next = NULL;
return node;
}

// insert node at front of list
void push(struct node **head, int data)
{
struct node *node = new_node(data);
node->next = *head;
*head = node;
}

// free the list, deallocate each node's memory
void delete_list(struct node** head)
{
if(*head == NULL)
return;

struct node *next = NULL;
next = (*head)->next;
while(next != NULL)
{
next = (*head)->next;
// print address of the memory released
printf("Freeing %d\n", (int)*head);
free(*head);
*head = next;
}
}

现在,该结构在我的机器中为 8 字节(4 字节 int 和 4 字节指针)。现在,我对以下内容有点不确定,所以请帮助我:

  1. 当我调用 push()按顺序,内存是连续分配的吗?总是这样吗?我想这不可能,因为堆中的内存可能会碎片化。

  2. 假设分配的内存是连续的,那么它会间隔 8 个字节吗,因为 struct的大小是 8 个字节。在我的机器上,当我打印被释放内存的地址时,打印的内存地址在每次执行时相隔 16 个字节。为什么?
    Freeing 148025480
    Freeing 148025464
    Freeing 148025448
    Freeing 148025432
    Freeing 148025416
    Freeing 148025400
    Freeing 148025384
    Freeing 148025368
    Freeing 148025352
    <empty list>

  3. 现在如果内存没有为我们的整数数组连续分配(堆非常碎片化,内存需求非常大),我们使用指针算法通过递增地址来处理数组的每个元素每次增加 4(或者 int 的大小),难道我们不应该遇到一些没有被我们的程序保留的内存,从而退出程序吗?或者运行时环境是否足够智能来处理这个问题,因为编译器不能,因为它不知道如何分配内存。操作系统会处理这个吗?

最佳答案

每次调用 new_node 时,它都会调用 malloc()

您不能(或不应该)预测 malloc() 会在哪里找到您的内存。它依赖于操作系统和运行时。

在特定的操作系统上运行,在某些情况下,您可能会观察到连续调用 malloc() 的分配是连续的。然而,这种行为可能会在负载下发生变化,或者随着内核更新、libc 实现的变化或在各种其他条件下发生变化。

您可以假设通过一次调用 malloc() 分配的内存块是连续的(至少,就您的程序所见的指针而言)。您的程序不应假设任何其他有关连续性的内容。


如果这真的困扰您,您可以在自己的代码中负责更多的内存管理——而不是为每个节点调用 malloc(),而是在开始时调用它并获得一个更大的内存块。对 new_node 的后续调用可以使用该 block 的一部分。如果该 block 中的空间不足,您可以 malloc() 另一个 block (可能不会与第一个 block 连续)或 realloc() 来扩展(并可能移动)它。

您可能会发现,所有这些都会让您的代码变得更加复杂——至于是否有好处可以抵消这种情况,则取决于您。 Hotspot Java VM 的作者基本上是这样做的——他们在执行开始时 malloc() 一大块内存,然后调用 malloc()free() 当 Java 程序需要内存时,它会使用自己的例程来分配该 block 的各个部分。

关于c - 堆内存 : Gap of 16 bytes for 8 byte struct,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24535618/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com