用动态存储分配代替大块静态存储分配 ————用指针代替大数组 关于指针和数组的定义、使用、规则、内存分配等等在此不述,本小文主要通过几个测试程序说明在实际编程中有时需要用指针而不是数组来对一块存储区域进此操作,即使在一些方面比数组存在劣势,即使所需的存储区域大小是固定的。比如在使用大数组的时候要注意,有时存储分配不能成功而出现运行时“段错误”,而这种错误在编译时发现不了,而且也会让程序员挠头半天,“明明程序编写对了”。来看一个小程序: #include <stdlib.h> 这段程序很简单,主要注意数组语句部分:“POINT points[POINTNUM];”,理论上分析数组占用空间大小为sizeof(POINT)*POINTNUM=(4*96+4+4)*38400 B=15052800 B 约为14 MB,与物理内存相比小得多,但是执行时会出现“段错误”,调试程序发现问题出在这条语句上。但将POINTNUM改成10时,程序执行没出问题。#include <stdio.h> #define POINTNUM 38400 #define DIM 96 int main(int argc, char **argv) { typedef struct point{ float coords[DIM]; float value; //携带的值 float refValue; //邻居值 } POINT; printf("sizeof POINT: %d\n", sizeof(POINT)); POINT points[POINTNUM]; printf("sizeof points: %d\n", sizeof points); int n, m; for(n=0; n<POINTNUM; n++) //使用随机发生器产生一组粒子 { for(m=0; m<DIM; m++) { srand(n+m); points[n].coords[m] = rand() % 100; } srand(n); points[n].value = rand(); } return 1; } 分析:数组points的空间分配是在栈区创建的,分配的内存容量是有限制的[1]。在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域,意思是栈顶的地址和栈的最大容量是系统预先规定好的,在Windows下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow[2]。在linux下,栈的大小也是有限制的,具体多少不太清楚,也没有查到相关的资料,还望高人指点。 虽然网上说栈区大小可以设定,但毕竟编程者不想多此一举,而且也给代码移植带来麻烦,所以针对上文提到的问题,可以使用指针动态内存分配,空间是在堆区分配。代码如下: #include <stdlib.h>
#include <stdio.h> #define POINTNUM 38400 #define DIM 96 int main(int argc, char **argv) { typedef struct point{ float coords[DIM]; float value; //携带的值 float refValue; //邻居值 } POINT; POINT *points = (POINT *)malloc(sizeof(POINT)*POINTNUM); if(!points) { printf("memory allocate failure!\n"); return -1; } int n, m; for(n=0; n<POINTNUM; n++) //使用随机发生器产生一组粒子 { for(m=0; m<DIM; m++) { srand(n+m); points[n].coords[m] = rand() % 100; } srand(n); points[n].value = rand(); } free(points); return 1; } |
|
来自: BeautymengRoom > 《我的图书馆》