堆区(heap)内存操作
-
通过协调使用
malloc()
、calloc()
、memcpy()
、memset()
和free()
这些堆区内存操作函数,完成动态内存的分配、初始化、复制和释放的操作。
-
如果只需要分配内存而不需要初始化,使用
malloc()
,要分配并初始化内存为零,使用calloc()
;
申请与释放
malloc()
- 原型:
void *malloc(size_t size);
- 参数:
size
:要分配的内存块的大小,以字节为单位。
- 返回值:
- 如果分配成功,则返回指向分配内存块的指针。
- 如果分配失败,则返回
NULL
。
- 作用:分配指定大小的内存空间,并返回该内存空间的起始地址。。
- 使用方法:
- 调用
malloc()
函数并传入需要分配的内存块的大小作为参数。 - 检查返回值是否为
NULL
,以确认内存是否成功分配。 - 使用返回的指针来访问和操作分配的内存空间。
- 使用完毕后,需要调用
free()
函数来释放已分配的内存,以避免内存泄漏问题。
- 调用
calloc()
:
calloc()
函数用于动态分配内存并初始化为零。- 原型:
void *calloc(size_t num, size_t size);
- 参数:
num
:要分配的元素个数。size
:每个元素的大小(字节数)。
- 返回值:如果内存分配成功,则返回一个指向分配内存的指针;如果分配失败,则返回
NULL
。 - 作用:动态分配
num * size
字节大小的内存,并将分配的内存块中的每个字节都初始化为零。
free()
:
free()
函数用于释放动态分配的内存,以避免内存泄漏问题。。- 原型:
void free(void *ptr);
- 参数:要释放的内存块的起始地址。
- 返回值:无返回值。
- 作用:释放之前通过动态内存分配函数(如
malloc
、calloc
、realloc
等)分配的内存空间,以便系统可以重新使用这些内存块。
复制与用户设定
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;
}