一、动态内存函数
在使用动态内存函数时,要引头文件#include<stdlib.h>
1.malloc
void *malloc( size_t size );
malloc函数向内存中申请一块连续的空间,如果开辟成功,返回一个指向开辟好空间的指针,如果开辟失败,返回NULL指针,所以使用malloc时,要对返回值进行检查。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(sizeof(int) * 10);
if (p == NULL)
{
perror("malloc");
exit(-1);
}
else
{
....
}
return 0;
}
2.free
void free( void *ptr );
free函数用来释放动态开辟的空间,如果参数ptr为NULL指针,则函数什么事也不做。同时,释放完的指针应及时置为NULL,防止非法访问内存。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(sizeof(int) * 10);
if (p == NULL)
{
perror("malloc");
exit(-1);
}
else
{
for (int i = 0; i < 10; i++)
{
p[i] = i + 1;
printf("%d ", p[i]);
}
printf("\n");
free(p);
p = NULL;
}
return 0;
}
3.calloc
void *calloc( size_t num, size_t size );
calloc函数为num个大小为size的元素开辟一块空间,并把空间的每个字节初始化为0。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = malloc(sizeof(int) * 10);
if (!p)
{
perror("malloc");
exit(-1);
}
int* a = calloc(10, sizeof(int));
if (!a)
{
perror("calloc");
exit(-1);
}
printf("malloc:\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", p[i]);
}
printf("\n");
printf("calloc:\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
printf("\n");
free(p);
p = NULL;
free(a);
a = NULL;
return 0;
}
4.realloc
void realloc( void ptr, size_t size );
realloc函数用来对动态开辟内存大小进行调整。ptr时要调整的内存地址,size时调整之后的大小,返回值为调整之后的内存的起始位置。
realloc调整内存空间:
1.原空间之后有足够大的空间:要扩展内存就直接在原有空间之后追加,原来空间的数据不发生变化
2.原空间之后没有足够大的空间:在堆上另找一块合适的内存空间,把原空间的数据拷贝到新空间,free原空间,返回新空间的地址。
3.如果没有足够可用的内存空间返回NULL
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(sizeof(int) * 10);
if (!p)
{
perror("malloc");
exit(-1);
}
for (int i = 0; i < 10; i++)
{
p[i] = i;
}
int* ptr = (int*)realloc(p, sizeof(int) * 20);
if (!ptr)
{
perror("realloc");
exit(-1);
}
p = ptr;
ptr = NULL;
for (int i = 0; i < 20; i++)
{
printf("%d ", p[i]);
}
free(p);
p = NULL;
return 0;
}
二、常见的动态内存错误
1.对NULL指针的解引用操作
在使用之前,记得判断是否为NULL指针
2.对动态开辟空间的越界访问
3.对非动态开辟内存使用free释放
4.使用free释放一块动态开辟内存的一部分
5.对同一块动态内存多次释放
6.动态开辟内存忘记释放(内存泄漏)