C++ Learning 内存分布•C语言动态内存分配

内存分布

程序的内存可以大致分为以下几个部分:

栈(Stack)
  • 作用:用于存储局部变量函数调用的相关信息,如函数的参数、局部变量、返回地址等。
  • 特点:栈的分配和释放遵循后进先出(LIFO)原则。每次函数调用时,局部变量会被压入栈中,函数返回时,这些变量会被自动清理。
堆(Heap)
  • 作用:用于动态分配内存。通过 newmalloc 等操作申请内存,分配的内存区域会一直保留直到显式释放(通过 deletefree)。
  • 特点:堆内存大小只受到系统可用内存的限制,相比栈,堆的内存管理更加灵活,但也更容易出错(如内存泄漏和内存越界)。
全局/静态数据区(Data Segment)
  • 作用:用于存储全局变量、静态变量和常量数据。这些变量的生命周期贯穿整个程序的执行。
  • 特点:分为初始化和未初始化两部分
    • 初始化区:存储已初始化的全局变量和静态变量。
    • 未初始化区(BSS区):存储未初始化的全局变量和静态变量,系统会自动将它们初始化为0。
代码区(Text Segment)
  • 作用:存储程序的机器代码(即指令)。这一部分是只读的,程序运行时不可修改。
  • 特点:这部分内存中存储的是程序的二进制指令,程序的代码通常不占用大量内存,因此通常在程序启动时就被加载到内存中。
常量区(Constant Data Segment)
  • 作用:存储程序中使用的常量数据,如字符串常量等。
  • 特点:这部分通常是只读的,程序不能修改其中的内容。常量区一般与代码区共享一部分内存。

C语言动态内存分配

malloc (Memory Allocation)
  • 功能:用于分配指定大小的内存块。
  • 语法void* malloc(size_t size);
  • 参数size 为要分配的内存大小(字节数)。
  • 返回值:返回一个指向分配内存的指针。如果分配失败,返回 NULL
  • 特点:分配的内存没有初始化,内存中的数据是随机的。

注意:使用 malloc 后,必须检查返回值是否为 NULL,以确保内存分配成功。

calloc (Contiguous Allocation)
  • 功能:用于分配内存并将所有字节初始化为零
  • 语法void* calloc(size_t num, size_t size);
  • 参数:
    • num:需要分配的元素个数。
    • size:每个元素的大小(字节数)。
  • 返回值:返回一个指向分配内存的指针。如果分配失败,返回 NULL
  • 特点:与 malloc 不同,calloc 会将分配的内存清零(每个字节的值为 0),确保初始化为零。
realloc (Reallocation)
  • 功能:用于重新调整已分配内存的大小。可以增加或减少内存的大小。
  • 语法void* realloc(void* ptr, size_t size);
  • 参数:
    • ptr:指向已分配内存块的指针。
    • size:新的内存块大小(字节数)。
  • 返回值:返回一个指向新分配内存块的指针。如果分配失败,返回 NULL,且原始内存块不会被释放。
  • 特点:如果内存块大小增加,realloc 会尝试扩展现有内存块并保持原有数据。如果大小减少,realloc 会截断内存,并保留原有数据。注意,如果 realloc 返回 NULL,原有内存块不会被释放,需要自己处理。

注意

  • realloc 可以用来调整大小,但需要特别注意返回的指针,因为 realloc 可能会重新分配一块新的内存,原始指针将失效。如果使用返回的新指针赋值给原指针,之前的内存会被正确释放。
  • 如果 realloc 返回 NULL,表示重新分配失败,原始内存不会被释放。
总结
函数功能初始化参数返回值
malloc分配指定大小的内存size_t size分配内存的指针 / NULL
calloc分配指定数量和大小的内存,并初始化为0size_t num, size_t size分配内存的指针 / NULL
realloc调整已经分配的内存块的大小void* ptr, size_t size新内存块指针 / NULL
小问题
void Test()
{
    int* p1 = (int*)malloc(sizeof(int));  // 动态分配内存
    free(p1);  // 释放p1指向的内存

    int* p2 = (int*)calloc(4, sizeof(int));  // 动态分配内存并初始化为0
    int* p3 = (int*)realloc(p2, sizeof(int) * 10);  // 调整p2的内存大小为10个整数

    free(p3);  // 释放p3指向的内存
}

问题 :是否需要 free(p2)

这个问题关键在于如何使用 realloc。在调用 realloc(p2, sizeof(int) * 10) 时,realloc 会尝试重新分配内存,并返回一个新的指针 p3

  • 如果 realloc 成功,返回的新指针会指向新分配的内存块,此时原来的 p2 指向的内存会被释放(即 p2 指向的内存被回收)。因此,原来的 p2 不再需要 free
  • 如果 realloc 失败,它会返回 NULL,此时原来的内存仍然有效,且需要释放。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值