常见的动态开辟内存的函数有以下三种
1.malloc
2.calloc
3realloc
malloc
void* malloc (size_t size);
size是内存块的大小(以字节为单位)。
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
printf("%s\n", strerror(errno));//打印错误信息
return 1;
}
//存放1-10
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i + 1;
}
//打印
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
//释放申请的内存
free(p);
p = NULL;
return 0;
}
其中free是用来释放开辟的动态内存的函数,这里在通过free()函数释放指针内存之后将其指针置空,这样可以避免后面的程序对与该指针非法性的判断所造成的程序崩溃问题。释放空间,指针的值并没有改变,无法直接通过指针自身来进行判断空间是否已经被释放,将指针置空有助于判断一个指针所指向的空间已经被释放。
而且动态指针是在堆上维护的,动态指针定义后,程序为指针分配了一块内存,而且保证这块内存不会被其他乱七八糟的东西修改。free的时候,是放弃了指针对这个内存的占用,放弃之后,内存的值会改写成随机值。但指针本身并没有被删除!指针仍然指向原来的那块内存!
使用free的时候还要注意一下几点:
如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
如果参数 ptr 是NULL指针,则函数无效
free函数的声明在<stdlib.h>头文件中
使用malloc的注意事项
如果开辟成功,则返回一个指向开辟好空间的指针。
如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
如果参数 size 为0,malloc的行为是是未定义的,具体情况取决于编译器。
malloc函数的声明在<stdlib.h>头文件中
calloc
void* calloc (size_t num, size_t size);
num是要分配的元素数,size是每个元素的大小,size_t是无符号整型。
int main()
{
int* p = (int*)calloc(10, sizeof(int));
if (p == NULL)
{
perror("calloc");//打印错误信息
return 1;
}
//使用
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
free(p);
p = NULL;
return 0;
}
malloc和calloc的功能和用法相似,二者有以下区别
参数不同;
malloc申请到的空间没有初始化就会直接返回起始地址,
calloc申请好空间后会把空间初始化为0然后返回起始地址。
到这里可能有人会有疑问:既然calloc不需要计算空间并且可以直接初始化内存避免错误,那为什么不只使用calloc函数,也就是为什么要使用malloc函数呢?
事实上,原因在于效率。calloc函数由于给每一个空间都要初始化值,那必然效率比malloc要低,并且有很多时候空间申请是不需要初始值的,这也就是为什么使用这两个函数的原因:各有优点。
realloc
void* realloc (void* ptr, size_t size);
ptr是指向原来空间地址的指针,size为接下来需要扩充容量的大小。
realloc函数和上面两个有本质的区别,用于对动态内存进行扩容(及已申请的动态空间不够使用,需要进行空间扩容操作)
int main()
{
int* p = (int*)malloc(5 * sizeof(int));
if (p == NULL)
{
perror("malloc");
return 1;
}
//使用
int i = 0;
for (i = 0; i < 5; i++)
{
*(p + i) = 1;
}
//不够后增加5个整型的空间
//如果扩容失败则返回NULL
int* ptr = (int*)realloc(p, 10 * sizeof(int));
if (ptr != NULL)
{
p = ptr;
ptr = NULL;
}
//继续使用空间
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
free(p);
p = NULL;
return 0;
}
上述代码是先通过malloc函数开辟了5个整型的空间,之后通过realloc函数继续对空间进行扩容,使用realloc函数的时候要注意:
realloc失败的时候,返回NULL。
realloc失败的时候,原来的内存不改变,也就是不free或不move。
假如原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存,realloc还是返回原来内存的地址;
假如原来的内存后面没有足够多剩余内存的话,realloc将申请新的内存,然后把原来的内存数据拷贝到新内存里,原来的内存将被free掉,realloc返回新内存的地址。
如果size为0,效果等同于free()。
传递给realloc的指针必须是先前通过malloc(), calloc() 或realloc()分配的 。