【堆区内存管理】堆区(heap)内存操作:协调使用 `malloc()`、`calloc()`、`memcpy()`、`memset()` 和 `free()` 函数操作堆区内存

堆区(heap)内存操作

  • 通过协调使用 malloc()calloc()memcpy()memset()free() 这些堆区内存操作函数,

    完成动态内存的分配、初始化、复制和释放的操作。

  • 如果只需要分配内存而不需要初始化,使用 malloc(),要分配并初始化内存为零,使用 calloc()

申请与释放

malloc()

  • 原型:void *malloc(size_t size);
  • 参数:
    • size:要分配的内存块的大小,以字节为单位。
  • 返回值:
    • 如果分配成功,则返回指向分配内存块的指针。
    • 如果分配失败,则返回 NULL
  • 作用:分配指定大小的内存空间,并返回该内存空间的起始地址。。
  • 使用方法:
    1. 调用 malloc() 函数并传入需要分配的内存块的大小作为参数。
    2. 检查返回值是否为 NULL,以确认内存是否成功分配。
    3. 使用返回的指针来访问和操作分配的内存空间。
    4. 使用完毕后,需要调用 free() 函数来释放已分配的内存,以避免内存泄漏问题。

calloc()

  • calloc() 函数用于动态分配内存并初始化为零
  • 原型:void *calloc(size_t num, size_t size);
  • 参数:
    • num:要分配的元素个数。
    • size:每个元素的大小(字节数)。
  • 返回值:如果内存分配成功,则返回一个指向分配内存的指针;如果分配失败,则返回 NULL
  • 作用:动态分配 num * size 字节大小的内存,并将分配的内存块中的每个字节都初始化为零。

free()

  • free() 函数用于释放动态分配的内存,以避免内存泄漏问题。。
  • 原型:void free(void *ptr);
  • 参数:要释放的内存块的起始地址。
  • 返回值:无返回值。
  • 作用:释放之前通过动态内存分配函数(如 malloccallocrealloc 等)分配的内存空间,以便系统可以重新使用这些内存块。
复制与用户设定

memcpy()

  • memcpy() 函数用于在内存之间复制一定数量的字节数据
  • 原型:void *memcpy(void *dest, const void *src, size_t n);
  • 参数:
    • dest:目标内存地址,表示复制后数据的存放位置。
    • src:源内存地址,表示要复制的数据的起始位置。
    • n:要复制的字节数。
  • 返回值:返回 dest 的值,即目标内存地址。
  • 作用:将 src 指向的内存区域的数据复制到 dest 指向的内存区域,通常用于复制数组、结构体等数据。

memset()

  • memset() 函数用于将一块内存区域设置为指定的值,多用于初始化,确保函数的可循环调用

  • 原型:void *memset(void *s, int c, size_t n);

  • 参数:

    • s:要设置值的内存区域的起始地址。
    • c:要设置的值,通常是一个字符或者整数。
    • n:要设置的字节数。
  • 返回值:返回 s 的值,即起始地址。

  • 作用:将 s 指向的内存区域的前 n 个字节都设置为值 c,通常用于初始化内存块。

  • 典例:

    	/* 申请内存空间并清零 */
        mt = calloc(max_slots, sizeof(struct ts_mt));
    	/* 对缓冲区初始化操作 */
        memset(mt, 0x0, max_slots * sizeof(struct ts_mt));  //清零(初始化)
    
    	/*.............(对申请的内存空间的利用)*/
    	free(mt);											//释放
    
    
何时需要堆区内存操作
  • 动态分配内存
  • 返回指向动态分配内存指针
  • 传递指针给函数并在函数内部修改指针指向的内容(双重指针)则需动态分配内存
    • 函数传入的是一个指针
    • 内容需要修改,所以是动态分配内存

典例详情移步笔者另外一文【指针(双重指针部分)】:https://blog.csdn.net/Thmos_vader/article/details/141115124

int ts_read_mt(struct tsdev *ts, struct ts_sample_mt **samp, int max_slots, int nr)
提前定义:
	struct ts_sample_mt *mt_ptr = NULL;
	
第三个参数(struct ts_sample_mt* *samp)一个双重指针
	指针samp指向一个结构体指针,外部传参需传入一个指向结构体指针的指针的地址即为 &mt_ptr(见上);

这里只挑出来讲明白这玩意儿就行。

内存操作典例

首先使用 calloc() 分配了一个包含5个整数元素的数组,并将数组中的每个元素初始化为零。

然后使用 memset() 将数组中的元素初始化为特定值。

接着使用 memcpy() 复制了一个整数数组到动态分配的数组中,并输出复制后的数据。

最后使用 free() 释放了动态分配的内存。

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

int main() {
    // 动态分配内存并初始化为零
    size_t num_elements = 5;
    size_t element_size = sizeof(int);
    int *array = (int *)calloc(num_elements, element_size);
    
    // 检查内存是否成功分配
    if (array == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }
    
    // 使用 memset() 初始化内存为特定值
    int init_value = 10;
    memset(array, init_value, num_elements * element_size);
    
    // 使用 memcpy() 复制数据
    int source[] = {1, 2, 3, 4, 5};
    memcpy(array, source, num_elements * element_size);
    
    // 输出复制后的数据
    printf("Copied array: ");
    for (int i = 0; i < num_elements; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
    
    // 释放动态分配的内存
    free(array);
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值