因为当我们创建类型时,int类型固定是四个字节,char arr[10]固定是十个字节。但是我们对与空间的需要是在程序运行的时候不断发生变化的,所以这个时候数组的开辟空间就很可能不能满足。这个时候就需要动态内存开辟。
栈区:局部变量,函数的形参。
堆区:malloc/free,calloc,realloc,动态内存分配。
静态区:全局变量,静态变量。
malloc用于开辟内存块,返回的是一个void*的指针,指向开辟空间的起始地址。当开辟空间不足而申请失败时返回一个NULL(空指针)。
#include
//#include 两者都可以
void *malloc(size_t size);
int main()
{
//int arr1[10];//40个字节
//char arr2[40];//40个字节
//申请空间
int* ptr = (int*)malloc(40); //空间过大,括号内为INT_MAX时会开辟失败。
int* p = ptr; //保存起始位置地址。
if (p == NULL)
{
perror("malloc");
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*p = i;
p++;
}
//释放空间,指向起始位置的ptr。
free(ptr); //此时空间不属于ptr,但是ptr任然存放该空间首地址,所以为野指针。
ptr = NULL; //这样就让ptr没有任何有效空间。
/*if (ptr != NULL)
{
*ptr = 100;
}*/
//*ptr = 100;//err
return 0;
}
void free (void* ptr);
//free同样也包含在头文件中。
//ptr指向的空间需要为动态开辟的,不是的话那么就会报错(free函数未定义)。
//ptr如果是NULL指针,那么函数声明也没不干。
free要求:
当我们不释放动态申请的内存的时候,当程序结束,动态申请的内存有操作系统自动回收,如果程序不结束,就会造成内存泄漏。因为动态内存不会自动回收。
void *calloc(size_t num, size_t size);
//num是元素的个数,size是元素的长度。
//例如:
int* p =(int *)calloc(10,sizeof(int));
//calloc申请的空间会被初始化成0。
与malloc不同的是calloc不仅申请了空间,还把空间初始化成了0。
用于内存的调整。
void *realloc(void *memblock,size_t size);
//memblock是扩容空间的起始地址,size是扩充空间的大小,单位为字节。
//头文件同前三个函数。
realloc函数会遇到两种情况,
成功:
当起始地址往后的内存足够的时候,便追加空间,追加空间和原本空间和为size。然后返回起始地址。
当起始地址往后内存不够的时候,会寻找一块长度足够的内存空间,把原数据拷贝过来,然后返回新内存空间的首地址。把原内存不够的数据的空间free掉。
失败:
返回一个空指针。因此需要ptr来接收。
int main()
{
int*p = (int*)malloc(40);
if (p == NULL)
{
perror("malloc");
return 1;
}
//使用
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;//0 1 2 3 4 5 6 7 8 9
}
//空间不够,希望能放20个元素,考虑扩容
int*ptr = (int*)realloc(p, 80);
if (ptr != NULL)
{
p = ptr;
}
//扩容成功了,开始使用
//不再使用,就释放
free(p);
p = NULL;
return 0;
}
int main()
{
int* p = (int*)malloc(1000);
int i = 0;
if (p == NULL)
{
//....
return 1;
}
//使用
for (i = 0; i < 250; i++)
{
*(p + i) = i;
}
free(p);
p = NULL;
return 0;
}
int main()
{
int* p = (int*)malloc(100);
int i = 0;
if (p == NULL)
{
//....
return 1;
}
//使用
//越界访问了
for (i = 0; i <= 25; i++)
{
*(p + i) = i;
}
return 0;
}
int main()
{
int a = 10;
int* p = &a;
//.....
free(p);
p = NULL;
return 0;
}
//因为a不是动态开辟的空间,所以会报错。
int main()
{
int* p = (int*)malloc(100);
if (p == NULL)
{
return 1;
}
//使用
int i = 0;
for (i = 0; i < 10; i++)
{
*p = i;
p++; //不断++的时候释放时不再位于起始位置。
}
//释放空间
free(p);//err
p = NULL;
return 0;
}
int main()
{
int* p = malloc(100);
if (p == NULL)
return 1;
free(p);
//....
free(p);//err
p = NULL;
return 0;
}
void test()
{
int* p = malloc(100);
//使用
}
int main()
{
test();
//.....
while (1)
{
;
}
return 0;
}