标签:class 文件中 数组 赋值 数组元素 部分 过程 scanf amp
在数组一章中,介绍过数组的长度是预先定义好的,在整个程序中固定不变,但是在实际的编程中,往往会发生这种情况,即所需内存空间取决于实际输入的数据,而无法预先确定。为了解决上述问题,c语言提供了一些内存管理函数,这些内存管理函数可以按需要动态的分配内存空间,也可把不再使用的空间回收再次利用
静态分配、动态分配
静态分配
在程序编译或运行过程中,按事先规定大小分配内存空间的分配方式 int a[10]
必须事先知道所需空间的大小
分配在栈区或全局变量区,一般以数组的形式
按计划分配
动态分配
在程序运行过程中,根据需要大小自由分配所需空间
按需分配
分配在堆区,一般使用特定的函数进行分配
动态分配函数
所需头文件 include ‘stdlib.h‘
malloc函数
函数原型: void*malloc(unsigned int size)
功能说明
在内存的动态存储区(堆区)中分配一块长度为size字节的连续区域,用来存放类型说明指定的类型。函数原型返回 void* 指针,使用时必须做相应的强制类型转换;分配的内存空间内容不确定,一般使用memset初始化.
返回值: 分配空间的起始地址(分配成功) NULL(分配失败)
注意:
在调用malloc之后,一定要判断一下,是否申请内存成功
如果多次malloc申请的内存,第一次和第二次申请的内存不一定是连续的
举例
include ‘stdlib.h‘
include ‘stdio.h‘
include ‘string.h‘
int main(){
int count,*array,n;
printf("请输入您要申请的数组元素个数\n");
scanf("%d",&n);
array = (int*)malloc(n *sizeof(int));
if (array = NULL)
{
printf("申请内存失败\n");
return 0;
}
memset(array,0,n*sizeof(int));
for(count=0;count<n;count++)
{
array[count] =count;
}
for(count = 0;count<n;count++)
{
printf("%d\n",array[count]);
}
free(array); //释放array指向的内存
return 0;
}
free 函数(释放内存函数)
函数定义 void free(void*ptr)
函数说明 :free函数释放ptr指向的内存
注意 ptr指向的内存必须是 malloc calloc relloc 动态申请的内存
注意
free后,因为没有给p赋值,所以p还是指向原先动态申请的内存.
一块动态申请的内存只能free一次,不能多次free
calloc函数
函数定义 void *calloc(size_t,nmemb,size_t,size);
size_t 实际是无符号整型,它是在头文件中,用typedef定义出来的
函数的功能:在内存的堆中,申请nmemb块,每块的大小为size个字节的连续区域
函数的返回值
返回 申请的内存的首地址(申请成功)
返回NULL(申请失败)
注意: malloc和calloc 函数都是用来申请内存的
区别:
函数的名字不一样
参数的个数不一样
malloc申请的内存,内存由存放的内容是随机的,不确定的,而calloc函数申请的内存中的内容为0
调用方法
char*p = (char *)calloc(3,100)
在堆中申请了3块,每块大小为100个字节,即300个字节连续的区域
relloc 函数 (重新申请内存)
咱们调用的malloc 和calloc函数 单次申请的内存是连续的,两次申请的两块内存不一样连续,有些时候有这种需求,即我先用malloc或者calloc申请了一块内存,我还想再原内存上申请,或者我开始时候使用malloc或者calloc申请了一块内存,我想释放后边的一部分内存,为了解决这个问题,发明了relloc函数
函数的定义: void*relloc(void *s,unsigned int newsize)
函数的功能:
再原先s指向的内存基础上重新 申请内存,新的内存的大小为 new_size 如果原先内存后面有足够大的空间,就追加,如果后边的内存不够用,则relloc 函数会,找一个newsize 个字节大小的内存申请,将原先内存中的内容拷贝过来,然后存进新内存的地址
如果newsize比原先的内存小,则释放原先内存的后面的存储空间。只留下前面的newsize返回值:新申请的内存的首地址
举例
char *p;
p = (char* )malloc (100);
//咱们想在100个字节后面追加50个字节
p = (char *)relloc (p,150);//p指向的内存的新的大小为150个字节
char *p;
p = (char *)malloc(100);
//咱们想重新申请内存,新的大小为50个字节
p = (char*)relloc(p,50);// p指向的内存的新的大小为50个字节,100个字节后的50个字节被释放了
注意: malloc calloc relloc 动态申请的内存 ,只有再free或程序结束的时候才释放
内存泄漏
内存泄漏的概念:
申请的内存,首地址丢了,找不了,再也没法使用了,也没法释放了,这块内存就被泄漏了.
举例
int main(){
char*p;
p = (char*)malloc(100);
// 接下来,可以用p指向的内存了
p = "hello world";// p 指向别的地方了
//从此以后,再也找不到你申请的100个字节了,则动态申请的100个字节就被泄漏了
}
void fun(){
char *p;
p = (char*) malloc(100);
// 接下来,可以用p指向的内存了
}
int main(){
fun();
fun();
return 0;
//加个free(p); 就解决了内存泄漏
// 每调用一次fun 泄漏100个字节
}
解决方法2
char*fun(){
char *p;
p = (char*) malloc(100);
// 接下来,可以用p指向的内存了
return p;
}
int main(){
char *q;
q=fun(); //可以通过q使用,动态申请的100个字节的内存了
//记得释放
free(p);
// 每调用一次fun 泄漏100个字节
}
总结:申请的内存,一定不要把首地址给丢了,在不用的时候一定要释放内存
标签:class 文件中 数组 赋值 数组元素 部分 过程 scanf amp
原文地址:https://www.cnblogs.com/fengzi759/p/11618708.html