这些基础不要瞧不上——C的内存操作函数

133 阅读4分钟

在C/C++编程中,内存操作是至关重要的一环。合理使用内存操作函数不仅能提升程序的性能,还能提高代码的稳定性和安全性。本文将介绍几种常用的内存操作函数,包括malloc、calloc、realloc、free、memset、memcpy和memmove等,并提供相应的示例代码。

1. 动态内存分配函数

在C/C++中,动态内存分配用于在运行时分配内存,而不是在编译时确定内存大小。主要的动态内存分配函数有malloc、calloc和realloc。

1.1 malloc

malloc函数用于分配指定大小(以字节数)的内存块,返回一个指向该内存块的指针。分配的内存未被初始化。

//分配未初始化的内存块
//param size: 要分配的字节数
void* malloc(size_t size);

例如,分配一个整数数组:

int* arr = (int*)malloc(10 * sizeof(int));

1.2 calloc

calloc函数类似于malloc,用于分配内存块,只是calloc会将所有字节初始化为零。

//分配并初始化内存块
//param num: 要分配的元素个数
//param size: 每个元素的字节数
void* calloc(size_t num, size_t size);

例如,分配并初始化一个整数数组:

int* arr = (int*)calloc(10, sizeof(int));

1.3 realloc

realloc函数用于调整先前分配的内存块的大小。如果新大小大于原大小,未初始化的新内存块内容是未定义的;如果新大小小于原大小,超出部分的内存将被释放。

//调整内存块大小
//param ptr: 要调整的内存块指针
//param size: 新的字节数
void* realloc(void* ptr, size_t size);

注意

  • 如果size大于原大小,未初始化的新内存块内容是未定义的;

  • 如果size小于原大小,超出部分的内存将被释放;

例如,调整数组大小:

arr = (int*)realloc(arr, 20 * sizeof(int)); // 扩大内存
arr = (int*)realloc(arr, 5 * sizeof(int)); // 缩小内存

1.4 free

free函数用于释放先前分配的动态内存,避免内存泄漏。

//释放动态内存
//param ptr: 要释放的内存块指针
void free(void* ptr);

例如,释放数组:

free(arr);

2. 内存操作函数

内存操作函数用于在内存块之间复制、移动或设置内存内容。主要的内存操作函数有memset、memcpy和memmove。

2.1 memset

memset函数将指定值设置到指定内存块中。

//设置内存块内容
//param ptr: 要设置的内存块指针
//param value: 要设置的值
//param num: 要设置的字节数
void* memset(void* ptr, int value, size_t num);

例如,将数组中的所有字节设置为零:

memset(arr, 0, 10 * sizeof(int));

2.2 memcpy

memcpy函数用于从一个内存块复制数据到另一个内存块。

//复制内存块内容
//param dest: 目标内存块指针
//param src: 源内存块指针
//param num: 要复制的字节数
void* memcpy(void* dest, const void* src, size_t num);

注意

  • 源和目标内存块不能重叠;

  • 源和目标内存块的大小必须大于等于num;

例如,复制数组:

int src[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
memcpy(arr, src, 10 * sizeof(int));

2.3 memmove

memmove函数类似于memcpy,但它允许源和目标内存块重叠。memmove会根据源和目标内存块的位置关系,选择合适的复制方向以避免数据覆盖。

//移动内存块内容
//param dest: 目标内存块指针
//param src: 源内存块指针
//param num: 要移动的字节数
void* memmove(void* dest, const void* src, size_t num);

例如,移动数组元素:

int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
memmove(arr + 2, arr, 5 * sizeof(int)); // 将前5个元素向后移动2个位置

在这个例子中,memmove会先判断目标和源内存块的位置关系,然后选择合适的复制方向,确保数据不被覆盖。这种特性使得memmove在处理重叠内存块时更加安全和可靠。

3. 内存比较函数

内存比较函数用于比较两个内存块的内容,返回比较结果。主要的内存比较函数有memcmp。

//比较内存块内容
//param ptr1: 第一个内存块指针
//param ptr2: 第二个内存块指针
//param num: 要比较的字节数
//return: 如果相等返回0,否则返回非零值
int memcmp(const void* ptr1, const void* ptr2, size_t num);

例如,比较两个数组:

int result = memcmp(arr, src, 10 * sizeof(int));

4. 总结

了解和掌握C/C++中的内存操作函数,对于编写高效和稳定的程序至关重要。malloc、calloc、realloc和free提供了动态内存分配和释放的功能,而memset、memcpy和memmove则允许我们对内存块进行灵活的操作。通过合理使用这些函数,可以更好地管理程序中的内存,提升整体性能和安全性。