首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >堆内存:8字节结构的16字节间隙

堆内存:8字节结构的16字节间隙
EN

Stack Overflow用户
提问于 2014-07-02 15:49:05
回答 4查看 913关注 0票数 1

我使用下面的代码来创建一个新节点并将其插入到一个链接列表中,然后释放它们。

代码语言:javascript
复制
// 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的大小),难道我们不应该遇到程序没有保留的内存,抛出程序吗?或者运行时环境足够聪明来处理这个问题,因为编译器不能这样做,因为它不知道如何分配内存。操作系统会处理这个问题吗?
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-07-02 15:57:15

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

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

在特定的操作系统上运行,在某些情况下,您可能会发现,从连续调用到malloc()的分配是连续的。但是,这种行为在加载或内核更新时、在libc实现中的更改或在各种其他条件下都可能发生变化。

您可以假设对malloc()的单个调用分配的内存块是连续的(至少在程序看到的指针方面是这样的)。您的程序不应该假设其他任何关于毗连的东西。

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

您可能会发现,所有这些都会使您的代码变得更加复杂--这取决于您是否有解决这些问题的好处。Hotspot Java的作者基本上就是这样做的--他们在执行开始时使用了一个大的内存块,然后当Java程序需要内存时,它不会调用malloc()free(),而是使用自己的例程来分配块的一部分。

票数 3
EN

Stack Overflow用户

发布于 2014-07-02 16:19:08

关于#2,调用malloc的结果不完全连续的一个原因可能是元数据:当您请求x字节时,malloc实现可能为内部簿记过程分配一些额外的内存(标记块的大小、指向其他空闲块的指针等)。因此,对8个字节的请求实际上可能导致内部分配16个字节,因此连续分配之间的16字节间隔。

票数 3
EN

Stack Overflow用户

发布于 2014-07-02 15:52:46

如果使用malloc分配内存,则返回的内存将始终是连续的。

如果您两次调用malloc,就不能保证这两个分配将放在一起,即使两个malloc调用就在一起。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24535618

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档