您的位置:首页 > 其它

动态内存分配

2016-12-04 08:49 295 查看
为什么会有动态内存分配?

这是因为当你声明一个数组时,你必须使用一个编译时常量指定数组的长度,但是,数组的长度常常在运行时才知道,这是因为它所需要的内存空间取决于输入数据。而且这种方法人为的进行了数组大小的限制。

动态内存分配:
(堆区):是由程序员自己主动申请并释放的(在运行时开辟的空间)

1.malloc(申请大块内存)原型:

void *malloc( size_t size
);


一般最好写为malloc(sizeof(type)*nums)的形式

注意:malloc和free必须成对使用。
否则会导致内存泄漏(内存泄漏对常驻进程的影响最大)
将空间free后需要将指针置空,避免产生野指针。

malloc是以字节申请空间的,并且申请的空间会比实际要申请的空间大一些,多出来的空间一般保存申请的空间的一些信息,比如申请的空间大小。
需注意:
        1.判断申请的空间是否成功。
        2.free后也应该将该指针置空。
        3.使用申请的空间后的内容会出错,就是访问的内容越界。

2.calloc(功能相当于malloc+memset的功能):分配空间并会将空间初始化为0

函数原型如下:
void *calloc( size_t num, size_tsize);
缺点:由于要进行初始化,所以比起malloc,它的效率较低。

3.realloc:修改原先已经分配好的内存块的大小。

函数原型如下:
void *realloc( void *memblock, size_tsize);
memblock:已经分配好的空间的地址,size是需要分配的字节数。

使用的一般方式例如:
int *p = (int *)malloc(10*sizeof(int));
int *q =realloc (p,48);
free(q);-------注意,这时只需要free一个指针q就可以了。
这里的q必须有效,q为一个NULL 指针或者是由calloc,malloc,realloc所申请的。

使用realloc需要注意的问题:

1.当第一个参数为一个空指针时,它的功能就类似于malloc函数。

2.当第一个参数不为空时,并且它原先的内存块后面还有大量的空间可以使用时:这时直接扩展空间的大小。

3.当第一个参数不为空,但是它原先的内存块后面没有足够的空间可供使用时,将寻找其他地方重新开辟一段空间,如果可以找到足够大的空间开辟需要的空间大小时,那么就在其他地方重新开辟空间,并将原先内存块的内容拷贝到那块空间。而如果已经没有足够大的空间供你重新开辟的话,那么就扩展内存失败,返回NULL;

4.如果开辟的空间还要小于原先的内存块时,那么将会其他地方重新开辟空间,并将内容拷贝下来,将后面的的内存块进行部分释放。

realloc的正确使用方法:
(以防realloc扩展空间时,扩展失败,返回一个NULL,如果直接把返回值赋给先前已开辟好的空间的指针变量,可能会改变已经分配好空间的指针变量,所以先将realloc扩展空间的返回值保存在另一个指针变量中)。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>

int main()
{
char *p = (char *)malloc(10 * sizeof(char));
char *realp = NULL;
if (NULL == p)
{
printf("out of memory\n");
exit(1);
}
realp = (char *)realloc(p,20 * sizeof(char));
if (NULL == realp)
{
printf("out of memory\n");
exit(1);
}
else
{
p = realp;
strcpy(p,"hello\n");
printf("%s",p);
}
free(p);
system("pause");
return 0;
}


常见的动态内存使用错误:

1.对一个NULL指针进行解引用。
2.对分配的内存进行操作时越过边界,这点类似与数组的越过边界访问产生的错误。
3.释放并非动态分配的内存。
4.试图释放一块动态分配的内存的一部分以及一块动态内存被释放后被继续使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态内存分配