一、动态分配内存知识
动态内存分配:程序在运行的时候用malloc等函数在堆上申请任意多少连续的内存,程序员自己负责在何时用free释放内存。
动态内存分配的生存期由我们自己决定,使用非常灵活,但是问题相对也比较多;
如果没有释放的话,很容易就会造成内存溢出,因为堆中的内存块是全局的,因此不会因为函数的调用而结束。
二、动态分配内存的函数
动态分配内存的主要使用的函数有malloc,calloc,realloc,free包含在malloc.h或stdlib.h头文件中
1.malloc
void *malloc(size_t size) //返回的是一个通用类型的指针,根据需要去进行强转;
功能:允许从空闲内存池中分配连续内存但不初始化
参数:size参数实际就是一个所需字节数的整数
返回:若分配成功则返回一个指向该内存块的指针,在使用时可根据需要做强制类型转换,否则返回NULL(空指针)//需要判空
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//筛选法求素数
void SiftPrime(int n)
{
int *p = (int *)malloc(n*sizeof(int));//等同int p[n];
assert(p != NULL);//判断指针p是否为空
if(p == NULL)
{
return ;
}
int i;
for(i=0;i<n;i++)//所有的数标记为1
{
p[i] = 1;
}
p[0] = p[1] = 0;
for(i=2;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(j%i == 0)
{
p[j] = 0;//如果是不是素数则标记为0
}
}
}
for(i=0;i<n;i++)//输出标记为1的数,即为素数
{
if(p[i] != 0)
{
printf("%d\n",i);
}
}
}
int main()
{
SiftPrime(20);
return 0;
}
特别解释一下int *p = (int *)malloc(n*sizeof(int));
这条语句就是申请n*sizeof(int)这么长字节则内存,强转为int*,赋值给设置的整形指针变量p
2.calloc
void *colloc(size_t num_elements,size_t element_size);
功能:功能同malloc是一样的,但是作初始化
参数:num_elements是所需的元素的数量,element_size是每个元素的字节数
返回:同malloc函数一样
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main()
{
/*//如下操作等同calloc
int *arr = (int *)malloc(10*sizeof(int));
for(int i=0;i<10;i++)
{
arr[i] = 0;
}*/
int *arr = (int *)calloc(10,sizeof(int));//0,0,0,
return 0;
}
3.realloc
void *realloc(void *ptr,size_t new_size);
功能:在指针ptr指向的内存基础上扩大或者缩小内存
参数:ptr是指向先前通过malloc,calloc和realloc函数后分配的内存块的指针,new_size是内存块的新尺寸(可以小于原尺寸)
int main()
{
int *p = (int *)realloc(p,10*sizeof(int));
//下面的代码等同realloc
int *q = (int *)malloc(20*sizeof(int));
for(int i=0;i<10;i++)
{
q[i] = p[i];
}
p = q;
q = NULL;
return 0;
}
特别注意
1:当扩展内存的时候,不会对添加进内存块的字节进行初始化
2:若不能调整内存则返回NULL,但原有内存中的数据是不会发生改变的
3:若第一个参数为NULL那么功能 等同与malloc函数,若第二个参数为0,那么会释放调用内存块
realloc(NULL,10*size(int)) //等同malloc(10*sizeof(int));
realloc(p,0); //等同于free
4.free
功 能: 与分配函数配对使用,释放函数申请的动态内存。
(另:对于free(p)这句语句,如果p 是NULL 指针那么free 对p 无论操作多少次都不会出问题。如果p 不是NULL 指针,那么free 对p连续操作两次就会导致程序运行错误。)
用 法: void free(void *ptr);
free释放内存,不使用free则会出现内存泄漏,所以malloc下面的代码段出现了内存泄漏
free崩溃的原因
1、越界.漏写sizeof,realloc第二个参数写错
2、修改了指针的指向,p++
3、重复释放同一段内存
4、释放非动态内存