c - 堆的基本理解

标签 c memory-management heap-memory

我想了解更多关于堆上发生的事情。所以我看下面的C代码。它基本上只是在堆上为两个变量分配内存:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
    char *char_ptr;
    int *int_ptr;
    int mem_size;

    if(argc < 2)
        mem_size = 50;
    else
        mem_size = atoi(argv[1]);

    printf("\t[+] allocating %d bytes of memory on the heap for char_ptr\n", mem_size);
    char_ptr = (char *) malloc(mem_size);
    if(char_ptr == NULL)
    {
        fprintf(stderr, "Error: could not allocate heap memory. \n");
        exit(-1);
    }

    strcpy(char_ptr, "This is memory located on the heap.");
    printf("char_ptr (%p) --> '%s'\n", char_ptr, char_ptr);

    printf("\t[+] allocating 12 bytes of memory on the heap for int_ptr\n");
    int_ptr = (int * ) malloc(12);
    if(int_ptr == NULL)
    {
        fprintf(stderr, "Error: could not allocate heap memory.");
        exit(-1);
    }

    *int_ptr = 31337;
    printf("int_ptr  (%p) --> %d\n", int_ptr, *int_ptr);

    printf("\t[-] freeing char_ptr's heap memory...\n");
    free(char_ptr);

    printf("\t[+] allocating another 15 bytes for char_ptr\n");
    char_ptr = (char *) malloc(15);
    if(char_ptr == NULL)
    {
        fprintf(stderr,"Error: could not allocate heap memory.\n");
        exit(-1);
    }

   strcpy(char_ptr, "new memory");
   printf("char_ptr (%p) --> '%s'\n", char_ptr, char_ptr);

   free(int_ptr);
   free(char_ptr);
}

此代码的输出如下所示:

    [+] allocating 50 bytes of memory on the heap for char_ptr
char_ptr (0x8827008) --> 'This is memory located on the heap.'
    [+] allocating 12 bytes of memory on the heap for int_ptr
int_ptr  (0x8827040) --> 31337
    [-] freeing char_ptr's heap memory...
    [+] allocating another 15 bytes for char_ptr
char_ptr (0x8827050) --> 'new memory'

所以我猜 char_ptr 指向分配内存的开头 (0x8827008),对吧?

由于分配了 50 个字节,因此该内存的末尾应指向地址 0x882702A。下一个内存分配从地址 0x8827040 开始。我的问题是:为什么 int_ptr 不指向 0x882702B(第一次内存分配后的下一个地址)?或者换句话说:0x772702A0x8827040 之间的内存发生了什么?

最佳答案

具体取决于您的 C 库(反过来又取决于您的操作系统)。造成您所看到的现象的因素有两个:

  1. 您从 malloc 获得的每个内存块都带有一个 header (通常为 16 字节)作为前缀。然而,malloc 只返回一个指向 header 之后的指针。
  2. 每个内存块必须对齐,对齐到最大对齐单元的倍数。通常(取决于微处理器),最大对齐为 8 个字节。用于实现对齐的字节称为填充。

因此,以 ...2A 结尾的 block 被填充到 ...30,然后添加 16 字节的 malloc header ,下一个 block 从 ...40 开始。

关于c - 堆的基本理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27580332/

相关文章:

我可以将函数的参数称为标识符吗?

list - 强制重新计算列表

java - 内存使用量变化很快,正常吗?

delphi - 可以清除内存吗?

c++ - 将动态分配的变量 move 到 vector 中

java - 为什么存储长字符串会导致 OOM 错误,但将其分解为短字符串列表却不会?

C++ 指针容器

c - 动态多维数组

c++ - 无法理解 gadgetfs 中的部分代码

c - 我怎样才能从 glibc 中拦截一个函数并打印它的参数值?