存在动态内存分配的原因:
动态内存函数介绍:malloc, calloc,realloc,free
常见的动态内存错误
柔性数组
以int a=10; char a[10]=0;为例
空间开辟的大小是固定的;数组在声明的时候必须指定长度,内存在编译的时候分配
但是有时候我们需要的空间大小在运行的时候才能确定,内存在编译时分配就不适应了,
malloc 函数:void* malloc(size_t size)
向内存申请一块连续可用的空间,并返回指向这个空间的指针
如果开辟成功,返回指向开辟好的空间的指针
如果失败返回NULL, 返回值一定要检查
malloc返回值类型在具体使用的情况下,使用者自己决定
如果参数为0,malloc 是标准是未定义的,取决于编译器
free函数用来释放和回收空间
void free(void* str)
如果参数str所指的空间不是动态内存开辟的,free则是未定义的
如果str所指空间为空,free啥都不做
calloc函数在开辟空间的时候初始化为0;(在返回地址之前,把申请的空间初始化为0)比malloc 函数要多执行一步
void* calloc( size_t num,size_t size)
realloc函数
让动态内存更为灵活,申请大了,变小;申请小了;变大
void*realloc(*prt,size_t size)
prt 为原来的内存地址(要调整的);size_t size是调整后的大小
;这个函数除了会调整内存的大小,还会把原来地址中的数据,移到新空间中
两种情况:
情况2的利用效率高
常见错误:1,NULL指针的解引用错误(要判断指针为空)
例如:
void*test()
{
int*a=(int*)malloc(INT_MAX/4);
*p=20;
free(p);
}
2,越界访问
3,多次释放
4.释放一部分
5,忘记释放,对非动态内存开辟的空间进行释放
柔性数组
c99中结构中最后一个元素允许是未定义大小的数组
typedef struct str1
{ int i,
char name[],
} str1;
使用
int i=0;
*str1 p= (* str1 )malloc(sizeof(str1)+100 * sizeof(char));`
assert(p!=NULL);
p->i=100;
for(i=0;i<100;i++)
{
p->name[i]=i;
}
free(p);
p=NULL;
只释放一次,而且在使用的时候,用户不用担心内存到底释放几次的问题。
方法二:
typedef struct str1
{ int i,
char * name,
} str1;
*str1 p= (* str1 )malloc(sizeof(str1));
assert(p!=NULL);
p->i=100;
p->name=(char *)malloc(sizeof(char));
for(i=0;i<100;i++)
{ p->name[i]=i;
}
free(p->name);
p->name=NULL;
free(p);
p=NULL;
提高访问速度,其余的片放在寄存器中,速度就上去了(其实也上不了多少)
`