动态内存分配

动态内存分配

    1. malloc
    • 1.1函数原型
    • 1.2参数
    • 1.3特点
    • 1.4注意事项
  • 2.calloc
    • 2.1函数原型
    • 2.2参数
    • 2.3特点
    • 2.4注意事项
  • 3.realloc
    • 3.1函数原型
    • 3.2参数
    • 3.3特点
    • 3.4注意事项
  • 4.free
    • 4.1 函数原型
    • 4.2参数
    • 4.3特点
  • 结语

在 C 语言中,主要使用标准库函数 <stdlib.h> 中的几个函数来进行动态内存分配和释放,这些函数包括 malloc、calloc、realloc 和 free。

1. malloc

malloc 是 C 语言中动态内存分配函数之一,用于在程序运行时分配一块指定大小的内存空间。

1.1函数原型

c 复制代码
void* malloc(size_t size);

1.2参数

  1. size:表示要分配的内存大小,单位是字节。
  2. 返回值:
    成功时,返回一个指向分配的内存块的指针,该指针指向分配的内存空间的起始地址。
    如果分配失败(例如内存不足),则返回 NULL。

1.3特点

  1. 动态分配:malloc 分配的内存是在堆区动态分配的,其大小由程序运行时决定,而不是在编译时确定。
  2. 未初始化:malloc 分配的内存块内容是未初始化的,即内存中的值是随机的,可能包含垃圾数据。
  3. 需要手动释放:使用 malloc 分配的内存必须通过 free 函数手动释放,否则会导致内存泄漏。

1.4注意事项

  1. 检查返回值:在使用 malloc 后,必须检查返回值是否为 NULL,以避免使用未成功分配的内存。
  2. 释放内存:使用完 malloc 分配的内存后,必须调用 free 函数释放内存,避免内存泄漏。
  3. 类型转换:要将类型强转为所需赋值相对应的指针.

2.calloc

calloc 是 C 语言中另一个动态内存分配函数,与 malloc 类似,但它在分配内存的同时会自动初始化内存为零。这使得 calloc 在某些场景下比 malloc 更安全和方便。

2.1函数原型

c 复制代码
void* calloc(size_t num, size_t size);

2.2参数

  • num:要分配的元素数量。
  • size:每个元素的大小(以字节为单位)。
  • 返回值
    成功时,返回一个指向分配的内存块的指针,该指针指向的内存空间已被初始化为零。
    如果分配失败(例如内存不足),则返回 NULL。

2.3特点

  • 自动初始化:calloc 分配的内存会被初始化为零,这意味着分配的内存中所有字节的值都是 0。
  • 动态分配:与 malloc 一样,calloc 分配的内存位于堆区,其大小由程序运行时决定。
  • 需要手动释放:使用 calloc 分配的内存也必须通过 free 函数手动释放,否则会导致内存泄漏。

2.4注意事项

注意事项处与malloc大致相同,参考malloc;
如此,什么时候使用malloc什么时候使用calloc呢?

  • 当你需要分配一块内存并确保其内容为零时,calloc 是更好的选择。
  • 如果你只需要分配内存而不关心初始值,malloc 可能更高效。

3.realloc

realloc 是 C 语言中用于重新分配动态内存的函数。它可以在运行时调整之前分配的内存块的大小,同时保留原有内存中的数据(如果可能)。这使得 realloc 非常适合在程序运行过程中动态调整内存需求。

3.1函数原型

c 复制代码
void* realloc(void* ptr, size_t new_size);

3.2参数

  1. ptr:指向之前通过 malloc、calloc 或 realloc 分配的内存块的指针。
  2. new_size:新的内存块大小(以字节为单位)。
  3. 返回值
  • 如果重新分配成功,返回指向新分配内存块的指针。
  • 如果 new_size 为零,realloc 会释放原内存块并返回 NULL。
  • 如果内存重新分配失败(例如内存不足),realloc 会返回 NULL,但原内存块保持不变。

3.3特点

  1. 动态调整大小:realloc 可以增大或减小内存块的大小。
  2. 数据保留:
    如果新大小大于原大小,原内存块中的数据保持不变,新增部分的内容未定义(可能包含垃圾数据)。
    如果新大小小于原大小,原内存块中的数据会被截断,但保留的部分内容保持不变。
  3. 内存移动:如果无法在原内存块的位置进行扩展或收缩,realloc 会分配一个新的内存块,并将原数据复制到新内存块中。此时,原内存块会被释放。
  4. 需要手动释放:如果 realloc 返回的指针被赋值给原指针变量,且重新分配失败(返回 NULL),原内存块会被释放,导致数据丢失。因此,使用 realloc 时需要特别小心。

3.4注意事项

  1. 检查返回值:realloc 的返回值必须检查是否为 NULL,以避免使用无效指针。
  2. 避免内存泄漏:
    如果 realloc 返回 NULL,原内存块仍然有效,必须手动释放。
    如果 realloc 成功,原指针变量必须更新为返回的新指针。
  3. 内存移动:如果 realloc 分配了新的内存块,原内存块中的数据会被复制到新内存块中,原内存块会被释放。
  4. new_size 为零:如果 new_size 为零,realloc 会释放原内存块并返回 NULL。这种行为类似于 free,但需要特别注意,因为原指针不再有效。
    使用场景
    当你需要动态调整内存大小时,例如在读取文件内容时,根据文件大小动态调整缓冲区大小。
    在实现动态数据结构(如动态数组、链表等)时,realloc 可以方便地调整内存大小。

4.free

free 是 C 语言中用于释放动态分配的内存的函数。它与 malloc、calloc 和 realloc 配合使用,用于释放这些函数分配的内存,从而避免内存泄漏。

4.1 函数原型

c 复制代码
void free(void* ptr);

4.2参数

ptr:指向要释放的内存块的指针。该指针必须是之前通过 malloc、calloc 或 realloc 分配的内存块的起始地址。

4.3特点

  1. 释放内存:free 用于释放动态分配的内存。释放后,该内存块可以被系统重新分配给其他用途。
  2. 避免重复释放:如果尝试释放一个已经被释放的指针,可能会导致未定义行为(如程序崩溃或数据损坏)。因此,释放内存后,通常将指针设置为 NULL,以避免悬挂指针问题。
  3. 释放空指针:free(NULL) 是安全的,不会导致错误。这是一个有用的特性,可以在释放内存之前不检查指针是否为 NULL。
  4. 不改变指针值:free 只释放指针指向的内存,但不会改变指针本身的值。因此,释放内存后,必须手动将指针设置为 NULL,以防止后续误用。

结语

总的来说,动态内存分配malloc是申请内存但不初始化,而calloc比malloc多了一个初始化数据的过程,并且两者申请内存的参数是不一样的.而realloc主要是用来来修改内存空间的大小.三者在使用完之后,都要将所申请的空间给释放掉,以免造成内存空间泄露等一系列问题.并且要将指针置空,不要造成野指针之一问题.

相关推荐
m0_7482548821 分钟前
【华为OD机考】2024E+D卷真题【完全原创题解 详细考点分类 不断更新题目 六种主流语言Py+Java+Cpp+C+Js+Go】
java·c语言·华为od
Tlog嵌入式35 分钟前
[项目]基于FreeRTOS的STM32四轴飞行器: 三.电源控制
c语言·单片机·mcu·iot
solomonzw1 小时前
C++ 学习(八)(模板,可变参数模板,模板专业化(完整模板专业化,部分模板专业化),类型 Traits,SFINAE(替换失败不是错误),)
c语言·开发语言·c++·学习
John.Lewis4 小时前
C语言学习笔记-初阶(30)深入理解指针2
c语言·笔记·学习
我是大咖4 小时前
c语言笔记 野指针
c语言·开发语言·笔记
John.Lewis4 小时前
C语言学习笔记-进阶(1)深入理解指针3
c语言·笔记·学习
骑驴看星星a7 小时前
P10904 [蓝桥杯 2024 省 C] 挖矿
c语言·算法·蓝桥杯
Oracle_6668 小时前
《Linux C 智能 IO 矩阵:输入输出的自适应数据流转》
c语言·开发语言·microsoft
我爱蛋蛋后8 小时前
Linux驱动开发之ADC驱动与基础应用编程
linux·c语言·驱动开发·adc
commonbelive9 小时前
c语言、c++怎么将string类型数据转成int,怎么将int转成string
c语言·c++