C语言内存动态分配函数 您所在的位置:网站首页 c语言calloc和malloc C语言内存动态分配函数

C语言内存动态分配函数

2023-08-04 17:34| 来源: 网络整理| 查看: 265

内存动态分配函数

主要涉及malloc/calloc/realloc和free四个函数,头文件:#include

(1)malloc

函数原型:

void *malloc(size_t size);

说明

向系统申请分配一个长度为size大小字节的内存块,并返回内存块的起始地址。

返回值

如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。

演示示例:

#include #include int main() { /* 1. malloc返回的是void *类型,在需要时候的时候要做一个适合目标指针类型的转换,比如这里转换成int *; 如果是 char *p_a = (char *)malloc(10); */ int *p_a = (int *)malloc(10 * sizeof(int)); //int *p_a = (int *)malloc((size_t)(1024*1024*1024*2)); //执行此句就会执行失败, //所以malloc之后一定要做一个是否申请内存成功的判断 if (!p_a) { printf("malloc 失败, p_a = %p\n", p_a); exit(1); } // 2.malloc分配的内存它的值是随机 printf("malloc刚申请的一段内存其值是:\n"); for (int i = 0; i < 10; i++) { printf("%d ", *(p_a + i)); } printf("\n"); // 赋初值 for (int i = 0; i < 10; i++) { *(p_a + i) = i; } printf("初始化后的数据:\n"); for (int i = 0; i < 10; i++) { printf("%d ", *(p_a + i)); } printf("\n"); printf("free前的p_a = %p\n", p_a); free(p_a); //p_a = NULL; // 3. 测试free后指向的内存区域数值 printf("free后的p_a = %p\n", p_a); printf("测试free后指向的内存区域数值:\n"); for (int i = 0; i < 10; i++) { printf("%d ", *(p_a + i)); } printf("\n"); /* printf("测试free还往其指向的内存空间写数据:\n"); for (int i = 0; i < 10; i++) { *(p_a + i) = i; //往free后的空间写数据,程序出错 } */ printf("程序结束\n"); return 0; }

使用结论:

(1)malloc返回的是void *类型,在需要时候的时候要做一个适合目标指针类型的转换,

  比如char *p_a = (char *)malloc(10);

(2)malloc分配的内存它的值是随机;比如分配的字符串空间char *p_a = (char *)malloc(10),如果我们直接操作strlen(p_a)则结果不确定。可以用memset去赋予初值。

(3)在free后就不要再去操作该段内存区(不管是读还是写)。

(4)malloc后要判断内存是否申请成功。

(2)calloc

函数原型:

void *calloc(size_t n, size_t size);

返回值

如果分配成功则返回指向被分配内存的指针(此存储区中的初始值已被设置为0),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。

与malloc的区别

(1)传入参数不一样;

比如申请同样10个int的内存空间

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

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

(2)calloc申请的内存是有将其值初始化为0,而malloc则是随机的;

和malloc相同之处

(1)都是要用free去释放申请的内存;

(2)该段内存被free后都不要再去操作该段内存(不管读还是写)

什么使用calloc或malloc呢?

(1)如果你想把申请的内存区域初始化为0,可以使用calloc;

初始化为0是要花时间的。

(2)如果你的应用在内存申请后会手动赋予值,可以使用malloc。

即使你用了malloc,但是想把数据初始化为0,则用memset去初始化就可以了。

代码演示:

#include #include int main() { //int *p_a = (int *)malloc(10*sizeof(int)); // 1. calloc的参数和malloc有区别 int *p_a = (int *)calloc(10, sizeof(int)); if (!p_a) { printf("malloc 失败, p_a = %p\n", p_a); exit(1); } // 2. calloc申请的一段内存空间其值都被初始化为0 printf("calloc刚申请的一段内存其值是:\n"); for (int i = 0; i < 10; i++) { printf("%d ", *(p_a + i)); } printf("\n"); for (int i = 0; i < 10; i++) { *(p_a + i) = i; } printf("初始化后的数据:\n"); for (int i = 0; i < 10; i++) { printf("%d ", *(p_a + i)); } printf("\n"); printf("free前的p_a = %p\n", p_a); free(p_a); //p_a = NULL; // 3. 测试free后指向的内存区域数值 printf("free后的p_a = %p\n", p_a); printf("测试free后指向的内存区域数值:\n"); for (int i = 0; i < 10; i++) { printf("%d ", *(p_a + i)); } return 0; }

结果:

(3)realloc

函数原型

void* realloc(void* ptr, unsigned newsize);

给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度。

返回值

如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。

说明

realloc可以对给定的指针所指的空间进行扩大或者缩小,无论是扩大或是缩小,原有内存的中内容将保持不变。当然,对于缩小,则被缩小的那一部分的内容会丢失。

realloc并不保证调整后的内存空间和原来的内存空间保持同一内存地址。

比如

相反,realloc返回的指针很可能指向一个新的地址。

图示理解:比如要重新分配已经malloc的内存

代码演示:

#include #include int main() { int *p_a = (int *)malloc(10 * sizeof(int)); //申请10*sizeof(int)字节的空间 // 1. 给p_a指向的内存做初始化 for (int i = 0; i < 10; i++) { *(p_a + i) = i; // 赋值 } printf("\n初始化p_a指向内存的数值:\n"); for (int i = 0; i < 10; i++) { printf("%d ", *(p_a + i)); } // 1. 扩充数据,从10个int变为15个int printf("\n扩充之前p_a = %p\n", p_a); p_a = (int *)realloc(p_a, 15 * sizeof(int)); printf("扩充之后p_a = %p\n", p_a); printf("\n扩充之后的的数值:\n"); // 扩充后地址空间是很有可能发生变化的 for (int i = 0; i < 15; i++) { printf("%d ", *(p_a + i)); // 原有的内容的数值没有变化, 但扩充之后的数值是不确定的 } // 2. 缩减数据 p_a = (int *)realloc(p_a, 5 * sizeof(int)); printf("\n缩减之后p_a = %p\n", p_a); printf("\n缩减之后的的数值:\n"); // for (int i = 0; i < 15; i++) { printf("%d ", *(p_a + i)); // 缩减内存后被缩减部分的数据有变化 } // 测试越界使用 for (int i = 0; i < 10; i++) { *(p_a + i) = i; // 赋值 } free(p_a); p_a = NULL; // 内存释放后将p_a置为NULL,这是良好的编程习惯 printf("程序结束\n"); return 0; }

结果:

注意:

* (1)realloc扩充内存时,原有的数据不变,但扩充的内存的数值是不确定的;

* (2)扩展内存后其指针和原来可能不一样;

* (3)缩减内存后只能使用其指定长度的数据,不要越界使用。

思考:

使用malloc,memcpy和free去实现一个类似realloc的函数?

//待补充 (4)free

函数原型:

void free(void *ptr)

释放ptr指向的存储空间(ptr指向的内存需要由malloc/calloc或realloc动态申请)。

说明:

在释放内存后,建议将指针置为NULL,这是良好的编程习惯,如



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有