malloc
void*是因为malloc不知道会传什么类型的指针进来
size_t 类型表示C中任何对象所能达到的最大长度,它是无符号整数。
功能是向堆区申请空间,方便内存的分配
内存开辟失败返回的是空指针
成功返回只想开辟好的空间的指针
没有free会不会造成内存泄漏?
在程序退出时,会自动回收内存
什么是内存泄漏?
向堆区申请了空间,但没用了却未还,内存泄漏很麻烦
堆区是内存池,可以从堆区申请内存,程序不会自动清除
所以申请了空间还是free掉比较好,养成良好的编程习惯,成对出现!
使用
#include<stdio.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int arr[10] = { 0 };
int* p = (int*)malloc(40);//申请40个字节
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*(p+i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
free(p);
p = NULL;//把p置为NULL,怕之前的内存还能被找到
return 0;
}
如果你一直malloc,就会有很多内存碎片,性能会下降
为了维护内存空间,就开辟了内存池,也叫高性能内存池
calloc
ptr是要调整的内存空间
size_t size 是追加内存后的字节大小
和malloc略有不同
calloc会自动初始化为0;
上代码~
#include<stdlib.h>
#include<errno.h>
#include<stdio.h>
int main()
{
int*p=(int*)calloc(10, sizeof(int));
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
int i = 0;
for (i; i < 10; i++)
{
printf("%d ", *(p + i));
}
free(p);
p = NULL;
return 0;
}
realloc
更灵活的对内存进行调整,因为有时大有时小,realloc就能申请你需要的大小
realloc是怎么扩容的呢?
可能情况一:会覆盖别人的空间
可能情况二:直接在后面追加
realloc是怎么做的呢?
直接在足够大的空间开辟80byte把旧的再空间拷贝过来
扩容
#include<string.h>
#include<stdlib.h>
#include<errno.h>
#include<stdio.h>
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
for (int i = 0; i < 10; i++)
{
*(p+i) = i + 1;
}
int*ptr=(int*)realloc(p, 20*sizeof(int));
if (ptr!= NULL)
{
p = ptr;
}
for (int i=0; i < 10; i++)
{
printf("%d ", *(p + i));
}
free(p);
p = NULL;
return 0;
}
free
free必须释放动态开辟的内存空间
free的参数是NULL就什么也不干
常见的动态内存开辟错误
对NULL指针解引用操作
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}
对动态开辟空间的越界访问
void test()
{
int i = 0;
int *p = (int *)malloc(10*sizeof(int));
if(NULL == p)
{
exit(EXIT_FAILURE);
}
for(i=0; i<=10; i++)
{
*(p+i) = i;//当i是10的时候越界访问
}
free(p);
}
对非动态开辟内存使用free释放
void test()
{
int a = 10;
int *p = &a;
free(p);//ok?
}
使用free释放一块动态开辟内存的一部分
void test()
{
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置
}
对同一块动态内存多次释放
void test()
{
int*p=(int*)malloc(100);
free(p);
free(p);
}
动态开辟内存忘记释放(内存泄漏 )
void test()
{
int*p=(int*)malloc(100);
if(p!=NULL)
{
*p=20;
}
}
int main()
{
test();
while(1);
}
动态开辟的空间一定要释放,并且正确释放 。