一,我们先来介绍一下今天的第一个函数malloc:
参数:无符号整形。
返回值:void*的指针,内存开创成功后返回的是内存的起始地址,如果失败,返回NULL;
功能就是开辟指定大小的内存空间,但是不对该内存进行初始化,保留的是不确定的值。
我们在使用该函数的时候要注意对malloc之后的返回值进行强制类型转换,以便达到我们的使用目的。
接下来我们以一个例子来使用一下malloc
- #include
- #include
- #include
- int main()
- {
- //使用malloc开辟一块内存,并给该内存赋值。
- int* ptr = (int*)malloc(20);//开辟20个字节的空间
- int* p = ptr;
- //判断一下返回值是否正常
- if (p == NULL)
- {
- //显示一下错误信息,并介绍代码的运行
- strerror(errno);
- free(ptr);
- p = NULL;
- ptr = NULL;
- return 1;
- }
- for (int i = 0; i < 5; i++)
- {
- *p = i;
- p++;
- }
- for (int i = 0; i < 5; i++)
- {
- printf("%d ", *(ptr + i));
- }
- //释放
- free(ptr);
- ptr = NULL;
- p = NULL;
-
- return 0;
- }
无论在使用那个动态内存函数开辟的空间,大家在最后使用之后一定要注意用free()释放,释放时使用的时内存的首地址,所以我上面使用了p来进行赋值操作,但是这有点繁琐了,使用一个指针也是能完成上面的要求的,下面说代码的优化:
- #include
- #include
- #include
- int main()
- {
- //使用malloc开辟一块内存,并给该内存赋值。
- int* ptr = (int*)malloc(20);//开辟20个字节的空间
- //判断一下返回值是否正常
- if (ptr == NULL)
- {
- //显示一下错误信息,并介绍代码的运行
- strerror(errno);
-
- //这里可以不进行释放,因为我使用了return程序结束之后,内存就释放掉了!
- //free(ptr);
- //ptr = NULL;
- return 1;
- }
- for (int i = 0; i < 5; i++)
- {
- //这样ptr的值就没有改变。
- *(ptr + i) = i;
- }
- for (int i = 0; i < 5; i++)
- {
- printf("%d ", *(ptr + i));
- }
- //释放
- free(ptr);
- ptr = NULL;
-
- return 0;
- }
二,calloc函数:
同样我们还是先来看一下这个函数的返回值和参数以及功能有哪些
参数:num是开辟的字节大小,size是开辟的个数。
返回值:void*类型,开辟内存成功也是返回首地址,失败返回NULL;
与malloc不同的是,calloc会对开辟的内存进行一个初始化的操作,初始化全为0。
用例:
- int main()
- {
- //开辟4个字节的内存5个
- int* ptr = (int*)calloc(5, 4);
- //int* ptr = (int*)calloc(5, sizeof(int));
-
- if (ptr == NULL)
- {
- strerror(errno);
- return 1;
- }
- for (int i = 0; i < 5; i++)
- {
- *(ptr + i) = i;
- }
- for (int i = 0; i < 5; i++)
- {
- printf("%d ", *(ptr + i));
- }
-
- //释放
- free(ptr);
- ptr = NULL;
- return 0;
- }
calloc相比于malloc更加灵活了一些!,区别就是calloc会对内存初始化为0,而malloc不会。
三,realloc函数:
reaclloc函数可以更改指定内存块的大小
参数:ptr指向的内存块,size无符号整形
返回值:更改成功返回有两种可能性:
1,返回值原有的地址,2,返回新的地址
为什么会有这两种情况呢?原因是,当更改的内存和原有的内存是连续的话,更改完之后内存快的地址没有发生改变,返回的就是原地址。如下图:(减小原内存快空间的话返回的肯定是原地址)
并不是所有时刻更改的内存都是连续的,那么当更改的内存并不连续的时候realloc会新开辟一块大的空间,并将原数据拷贝到新开辟的内存快中,并返回新的内存地址!并将原内存块释放掉(自动释放)如下图:
注意,新分配出来的空间也是不进行初始化的!
如果更改不成功的话,返回NULL;
下面我们对第一例代码进行改造,让得能放下10个数据。
- #include
- #include
- #include
- int main()
- {
- int* ptr = (int*)malloc(20);
- if (ptr == NULL)
- {
- strerror(errno);
- return 1;
- }
-
- ptr = (int*)realloc(ptr, 40);
- for (int i = 0; i < 10; i++)
- {
- *(ptr + i) = i;
- }
- for (int i = 0; i < 10; i++)
- {
- printf("%d ", *(ptr + i));
- }
- //释放
- free(ptr);
- ptr = NULL;
-
- return 0;
- }
运行结果: