如果输入数据时,先告诉你个数,然后再输入,要记录每个数据。
C99可以用变量做数组定义的大小,C99之前呢?
int *a = (int*)malloc(n*sizeof(int));
代码如下:
#include<stdio.h> #include<stdlib.h> int main() { int number = 0; int *a = 0; int i = 0; printf("输入数量:"); scanf("%d",&number); a = (int*)malloc(number*sizeof(int)); for( i = 0; i<number; i++) { scanf("%d",&a[i]); } for( i = number - 1; i>=0; i--) { printf("%d ",a[i]); } free(a); }
malloc()
#include<stdlib.h>
void * malloc(size_t size);
1.向malloc申请的空间的大小是以字节为单位的
2.返回的结果是void*,需要类型转换为自己需要的类型
3.如果申请失败则返回0,或者NULL
试一试你的系统能给你多大的空间:
#include<stdio.h> #include<stdlib.h> int main() { void *p; int cnt = 0; while(p = malloc(100*1024*1024)) { cnt++; } printf("分配了%d00MB的空间\n",cnt); return 0; }
在我的电脑(64位 WIndows10家庭中文版,4G内存)上只能分配1900M的空间。
下面是来自知乎的讲解:
地址空间限制是有的,但是malloc通常情况下申请到的空间达不到地址空间上限。内存碎片会影响到你“一次”申请到的最大内存空间。比如你有10M空间,申请两次2M,一次1M,一次5M没有问题。但如果你申请两次2M,一次4M,一次1M,释放4M,那么剩下的空间虽然够5M,但是由于已经不是连续的内存区域,malloc也会失败。系统也会限制你的程序使用malloc申请到的最大内存。Windows下32位程序如果单纯看地址空间能有4G左右的内存可用,不过实际上系统会把其中2G的地址留给内核使用,所以你的程序最大能用2G的内存。除去其他开销,你能用malloc申请到的内存只有1.9G左右。
其实,操作系统版本、程序本身大小、乃至的动态/共享库数量和大小、程序栈数量和大小等都会对其造成影响,甚至有些操作系统使用了一种叫做随机地址空间分布的技术(主要是出于安全考虑,防止程序受恶意攻击),使得进程的堆空间变小。
一个由C/C++编译程序占用内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数参数值,局部变量值等。其操作方式类似于数据结构中栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量存储是放在一块,初始化全局变量和静态变量在一块区域, 未初始化全局变量和未初始化静态变量在相邻另一块区域。 – 程序结束后由系统释放。–>分别是data区,bbs区
4、文字常量区 —常量字符串就是放在这里。 程序结束后由系统释放–>coment区
5、程序代码区—存放函数体二进制代码。–>code区
而我们的malloc()申请的空间位于堆区,32位操作系统下理论最大可能申请到的空间是4G(内存达到4G且不算操作系统占用的内存时,实际做不到),64位操作系统下基本是根据内存决定的。
free()
1.把申请得来的空间还给“系统”
2.申请过的空间最终都应该还
3.只能还申请来的空间的首地址
4.free(0)和free(NULL)没问题,程序什么都不会归还
那么,malloc得到的空间是连续的吗?
逻辑地址连续,物理地址可以不连续。
malloc在大多实现中分配得到的内存空间比要求的大,额外空间记录管理信息——分配块的长度。
关于malloc(0)
1.来自C99的最权威的解释,malloc(0)是未定义行为:
2.返回一个地址空间是有意义的:为了和free的正常配对
3.malloc(0)的结果依赖实现