如果输入程序时,先告诉你个数,然后再输入,要记录每个数据(类似动态数组)
C99之前应该怎么做呢?
malloc()函数的作用就在此:
int *a = (int*)malloc(n*sizeof(int));
malloc()函数的作用是向内存申请一个n*sizeof(elementtype)的内存,并返回地址,申请过来的这个大小的内存,可以直接理解为新建了一个a[n]的数组
使用malloc(),需要添加头文件#include<stdlib.h>
在功能解释中,malloc的解释如下:
重点在
void *
malloc(size_t size);
可见,malloc的返回类型是void*,需要传递的数据是内存大小。
所以在给指针赋值的时候,必须将其进行强制类型转换(从void转到需要的类型),内存大小根据所需的数据类型设定,如int类型就是n * sizeof(int),char类型就是n * sizeof(char)
对于通过malloc()申请过来的内存,在最后(一个合适的时机)必须通过free(*a)将其释放,否则会造成其一直占用内存,对计算机的运行造成影响
代码尝试:
#include<stdio.h>
#include<stdlib.h>
int main(){
int num;
int *a;
int i;
printf("输入数量:");
scanf("%d",&num);
//int a[num]; c99可以这么用
a = (int*)malloc(num*sizeof(int));
for(i=0;i<num;i++){
scanf("%d",&a[i]);
}
for(i = num - 1;i>=0;i--){
printf("%d ",a[i]);
}
free(a);
return 0;
}
输入数量:5
1 3 4 3 2
2 3 4 3 1
malloc总结:
头文件:#include<stdlib.h>
void* malloc(size_t size);
·向malloc申请的空间的大小是以字节为单位的
·返回的结果是void*,需要类型转换为自己需要的类型
elementtype *a = (elementtype*)malloc(n*sizeof(elementtype));
对于结构体 其定义方式为
structname *a = (struct structname*)malloc(n*sizeof(struct structname));
能申请的空间大小是有限的,根据电脑自身RAM(内存)有关,如果申请失败则返回0,或者叫null
尝试一下此时自己电脑能申请多大的内存:
#include<stdio.h>
#include<stdlib.h>
int main(){
void *p;
int cnt = 0;
while((p = malloc(100*1024*1024))){
//1024b * 1024 = 1MB
//只要不free,每次申请的都是一个新的内存
cnt++;
}
printf("分配了%d00MB的空间\n",cnt);
return 0;
}
free()
·把申请过来的空间还给“系统”
·申请过的空间,最终都应该要还
·只能还申请来的空间的首地址
#include<stdio.h>
#include<stdlib.h>
int main(){
void *p;
p = malloc(100*1024*1024);
p++;
free(p);
return 0;
}
此时,程序会异常终止,因为p++后的这个地址并不是我申请过来的那个地址,所以并不能通过free去释放
#include<stdio.h>
#include<stdlib.h>
int main(){
int i;
void *p;
p = &i;
free(p);
return 0;
}
在TDM-GCC 4.9.2 64-bit中,并没有报错,运行后经过一段时间后程序结束,因为此时p不是我们通过malloc()申请过来的地址,所以不能通过free()释放
但是free(NULL);这是可行的
因此在指针初始化时,如果直接
void *p = 0;
free(p);
这样也是可行的,这多用于定义指针后忘记申请地址的意外情况