文章目录
(1).动态内存函数
在c语言中我们声明一个数组时一定要指定数组的长度,
有了动态内存函数,就可以动态地开辟数组地空间,下面是常用地动态内存函数介绍
1.malloc
malloc
其实是memory allocate
的缩写,顾名思义就是内存开辟的意思
void* malloc (size_t size)
形参: size_t size 开辟的空间的大小,单位为字节
返回值类型: void* 返回类型为 void* 的指针,指向开辟的空间
例子:
#include<stdio.h>
#include<stdlib.h>
int main()
{
//开辟40个字节的内存
int* p = (int*)malloc(sizeof(int) * 10);
for (int i = 0; i < 10; i++)
{
//赋值为0
*(p + i) = 0;
}
//打印
for (int j = 0; j < 10; j++)
{
printf("%d ", *(p + j));
}
return 0;
}
输出:
0 0 0 0 0 0 0 0 0 0
注意:
malloc
函数返回类型是void*
, 使用时要转换类型
2.free
free
函数是释放内存空间的函数
void free (void* ptr)
形参: void* ptr 指向要释放空间的指针
返回值类型: void 没有返回值
例子:
#include<stdio.h>
#include<stdlib.h>
int main()
{
//开辟四个字节的空间
int* p = (int*)malloc(sizeof(int));
//释放空间
free(p);
return 0;
}
3.calloc
calloc
函数也是开辟空间的函数,但是会把开辟的空间的值都设置为0
void* calloc (size_t num, size_t size)
形参: size_t num 元素的个数
size_t size 元素的大小
返回值类型: void* 返回类型为 void* 的指针,指向开辟的空间
例子:
#include<stdio.h>
#include<stdlib.h>
int main()
{
//分配40个字节的空间,并把里面的数据全设置为0
int* p = (int*)calloc(10, sizeof(int));
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
输出:
0 0 0 0 0 0 0 0 0 0
4.realloc
realloc
函数通常在需要扩容的时候使用
realloc
函数会新开辟一块空间
并且会把之前的数据复制到新开辟的空间上
void* realloc (void* ptr, size_t size);
形参: void* ptr 指向一块内存空间的指针
size_t size 重新开辟的内存空间大小,单位为字节
返回值类型: void* 返回类型为 void* 的指针,指向重新开辟的内存空间
例子:
#include<stdio.h>
#include<stdlib.h>
int main()
{
//开辟4个字节的空间
int* p = (int*)malloc(sizeof(int));
*p = 1;
//扩容为两个整形的空间,为8个字节
p = (int*)realloc(p, sizeof(int) * 2);
*(p + 1) = 2;
//打印
printf("%d %d", *p, *(p + 1));
//释放空间
free(p);
return 0;
}
输出:
1 2
(2).动态内存错误
虽然动态内存开辟让我们更方便地管理内存,
但有时候会导致一些问题,下面介绍几个常见的错误。
1.动态开辟的内存忘记释放
刚开始使用动态内存分配时,有时会忘记释放空间
这会导致内存的泄露。
示例:
#include<stdio.h>
#include<stdlib.h>
void test()
{
int* p = (int*)malloc(sizeof(int) * 10);
for (int i = 0; i < 10; i++)
{
*(p + i) = i;
}
for (int j = 0; j < 10; j++)
{
printf("%d ", *(p + j));
}
}
int main()
{
test();
}
在test函数里,开辟了空间,但是在这里开辟的空间应该被销毁
因为出了test函数,空间就不需要用到了,所以要释放空间
正确的写法为:
void test()
{
int* p = (int*)malloc(sizeof(int) * 10);
for (int i = 0; i < 10; i++)
{
*(p + i) = i;
}
for (int j = 0; j < 10; j++)
{
printf("%d ", *(p + j));
}
free(p);
}
2.越界访问开辟的空间
有时候我们会越界访问空间,这将会导致程序错误
如下面的程序:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p != NULL)
{
for (int i = 0; i < 11; i++)
{
*(p + i) = i; //i = 10时,越界访问了
}
free(p);
}
return 0;
}
屏幕上也是直接弹出了错误!!!
ps-> 这就需要在写代码时多加注意了! 🤶
3.对非动态开辟的内存使用free释放
有时候我们并不知道指针指向的空间是否是动态开辟的
当对这块空间释放时,这也会导致程序错误
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 1;
int* p = #
free(p); //对不是动态开辟的内存,释放内存
return 0;
}
程序发生错误
4.对NULL指针解引用
对NULL指针解引用,会引发异常
int main()
{
int* p = NULL;
printf("%d", *p);
return 0;
}
对NULL指针解引用这只能在调试时找到问题,运行程序时控制台什么都没显示