为什么存在内存分配
int a=10;//局部变量
int g_a=10;//全局变量
1.创建一个变量时会申请内存
内存分为一个大的区域
栈区
堆区
静态区
栈区存放局部变量,函数的形式参数等
堆区存放动态内存分配的空间
静态区存放全局变量,静态变量等
2.创建一个数组可以是局部变量也可以是全局变量
int arr[10];
但是这样创建数组的内存我们必须首先给出数组的长度,C语言是不可以创建变长数组的(C99的编译器可以)int arr[n];所以像这样在某些时候我们就不好申请内存,比如在存储一个班级学生的信息时,学生人数难免会有变动这是就会产生空间的浪费或者空间申请不够的情况,这时我们就需要动态内存分配。
malloc
void* malloc (size_t size);
int* p=(int*)malloc(sizeof(int));
if(p==NULL)
{
printf("%s\n",strerror(errno));
}
else
{
int i=0;
for(i=;i<10;i++)
{
*(p+i)=i;
}
for(i=0;i<10;i++)
{
printf("%d",*(p+i));
}
}
free(p);
这就是malloc函数的格式 void*是一种指针类型,当你申请好内存空间就把首地址传给你。但是malloc是会开辟失败的,比如当你只有4G的内存但是你要申请8G的内存这是就会申请失败,申请失败会返回一个空指针,所以我们就要对它进行处理。
free
当你malloc申请成功,然后不在使用这些空间时你就需要释放空间,把空间还给操作系统,free这个函数就是这个作用。这个在大工程中特别重要否则会造成内存泄漏,但是在平常练习中如果没有不会有什么影响,因为在进程结束时操作系统会自动收回空间。当你把某指针的内存释放后记得把该指针置NULL,不然该指针其实还可以找到那片空间。
*free只作用动态开辟出来的内存
calloc
void* calloc (size_t num, size_t size);
该函数跟malloc作用一样,只不过它在开辟空间时把申请的空间每个字节赋值为零了(初始化为零)。并且格式表达上有些细微的差别,一个是直接算出总元素的内存,一个是算出有几个元素每个元素多大。
realloc
p=(int*)realloc(p,40);//40之前的p代表原空间的地址
realloc可以调整动态内存的大小,当你malloc申请的内存不够时你可以使用realloc来调整动态开辟的内存,当你用同一个指针来realloc调整内存时这是要注意。当你malloc后续空间不够你realloc申请调整的大小时会在其它地方重新开辟一个空间再把全有数据拷贝过来,这时返回的地址和原来的空间的地址可能不一样,原地址会被废掉,而且当realloc开辟失败时,返回空,原地址也会被废掉,所以得用一个新的变量来接受realloc函数的返回值。
realloc使用注意事项:
1.如果p指向的空间之后有足够的内存空间可以追加,则直接追加,后返回p
2.如果p指向的空间之后没有足够的内存空间可以追加,则realloc函数会重新找一个新的内容区域,开辟一块满足需求的空间,并且把原来的内存中的数据拷贝过来,释放旧的内存空间,最后返回新开辟内存空间地址。