📄 alloc.c
字号:
/* Copyright (c) Colorado School of Mines, 1990./* All rights reserved. *//*****************************************************************************Allocate and free multi-dimensional arrays******************************************************************************Notes:The functions defined below are intended to simplify manipulationof multi-dimensional arrays in scientific programming in C. Thesefunctions are useful only because true multi-dimensional arraysin C cannot have variable dimensions (as in FORTRAN). For example,the following function IS NOT valid in C: void badFunc(a,n1,n2) float a[n2][n1]; { a[n2-1][n1-1] = 1.0; }However, the following function IS valid in C: void goodFunc(a,n1,n2) float **a; { a[n2-1][n1-1] = 1.0; }Therefore, the functions defined below do not allocate truemulti-dimensional arrays, as described in the C specification.Instead, they allocate and initialize pointers (and pointers to pointers) so that, for example, a[i2][i1] behaves like a 2-D array.The array dimensions are numbered, which makes it easy to add functions for arrays of higher dimensions. In particular,the 1st dimension of length n1 is always the fastest dimension,the 2nd dimension of length n2 is the next fastest dimension,and so on. Note that the 1st (fastest) dimension n1 is the first argument to the allocation functions defined below, but that the 1st dimension is the last subscript in a[i2][i1].(This is another important difference between C and Fortran.)The allocation of pointers to pointers implies that more storageis required than is necessary to hold a true multi-dimensional array.The fraction of the total storage allocated that is used to hold pointers is approximately 1/(n1+1). This extra storage is unlikelyto represent a significant waste for large n1.The functions defined below are significantly different from similar functions described by Press et al, 1988, Numerical Recipes in C.In particular, the functions defined below: (1) Allocate arrays of arbitrary size elements. (2) Allocate contiguous storage for arrays. (3) Return NULL if allocation fails (just like malloc). (4) Do not provide arbitrary lower and upper bounds for arrays.Contiguous storage enables an allocated multi-dimensional array tobe passed to a C function that expects a one-dimensional array.For example, to allocate and zero an n1 by n2 two-dimensional arrayof floats, one could use a = alloc2(n1,n2,sizeof(float)); zeroFloatArray(n1*n2,a[0]);where zeroFloatArray is a function defined as void zeroFloatArray(int n, float *a) { int i; for (i=0; i<n; i++) a[i] = 0.0; }Internal error handling and arbitrary array bounds, if desired,should be implemented in functions that call the functions defined below, with the understanding that these enhancements may limit portability.******************************************************************************Author: Dave Hale, Colorado School of Mines, 12/31/89*****************************************************************************/#include "cwp.h"/* allocate a 1-d array */void *alloc1 (size_t n1, size_t size){ void *p; if ((p=malloc(n1*size))==NULL) return NULL; return p;}/* re-allocate a 1-d array */void *realloc1(void *v, size_t n1, size_t size){ void *p; if ((p=realloc(v,n1*size))==NULL) return NULL; return p;}/* free a 1-d array */void free1 (void *p){ free(p);}/* allocate a 2-d array */void **alloc2 (size_t n1, size_t n2, size_t size){ size_t i2; void **p; if ((p=(void**)malloc(n2*sizeof(void*)))==NULL) return NULL; if ((p[0]=(void*)malloc(n2*n1*size))==NULL) { free(p); return NULL; } for (i2=0; i2<n2; i2++) p[i2] = (char*)p[0]+size*n1*i2; return p;}/* free a 2-d array */void free2 (void **p){ free(p[0]); free(p);}/* allocate a 3-d array */void ***alloc3 (size_t n1, size_t n2, size_t n3, size_t size){ size_t i3,i2; void ***p; if ((p=(void***)malloc(n3*sizeof(void**)))==NULL) return NULL; if ((p[0]=(void**)malloc(n3*n2*sizeof(void*)))==NULL) { free(p); return NULL; } if ((p[0][0]=(void*)malloc(n3*n2*n1*size))==NULL) { free(p[0]); free(p); return NULL; } for (i3=0; i3<n3; i3++) { p[i3] = p[0]+n2*i3; for (i2=0; i2<n2; i2++) p[i3][i2] = (char*)p[0][0]+size*n1*(i2+n2*i3); } return p;}/* free a 3-d array */void free3 (void ***p){ free(p[0][0]); free(p[0]); free(p);}/* allocate a 4-d array */void ****alloc4 (size_t n1, size_t n2, size_t n3, size_t n4, size_t size){ size_t i4,i3,i2; void ****p; if ((p=(void****)malloc(n4*sizeof(void***)))==NULL) return NULL; if ((p[0]=(void***)malloc(n4*n3*sizeof(void**)))==NULL) { free(p); return NULL; } if ((p[0][0]=(void**)malloc(n4*n3*n2*sizeof(void*)))==NULL) { free(p[0]); free(p); return NULL; } if ((p[0][0][0]=(void*)malloc(n4*n3*n2*n1*size))==NULL) { free(p[0][0]); free(p[0]); free(p); return NULL; } for (i4=0; i4<n4; i4++) { p[i4] = p[0]+i4*n3; for (i3=0; i3<n3; i3++) { p[i4][i3] = p[0][0]+n2*(i3+n3*i4); for (i2=0; i2<n2; i2++) p[i4][i3][i2] = (char*)p[0][0][0]+ size*n1*(i2+n2*(i3+n3*i4)); } } return p;}/* free a 4-d array */void free4 (void ****p){ free(p[0][0][0]); free(p[0][0]); free(p[0]); free(p);}/* allocate a 5-d array */void *****alloc5 (size_t n1, size_t n2, size_t n3, size_t n4, size_t n5, size_t size) { size_t i5,i4,i3,i2; void *****p; if ((p=(void*****)malloc(n5*sizeof(void****)))==NULL) return NULL; if ((p[0]=(void****)malloc(n5*n4*sizeof(void***)))==NULL) { free(p); return NULL; } if ((p[0][0]=(void***)malloc(n5*n4*n3*sizeof(void**)))==NULL) { free(p[0]); free(p); return NULL; } if ((p[0][0][0]=(void**)malloc(n5*n4*n3*n2*sizeof(void*)))==NULL) { free(p[0][0]); free(p[0]); free(p); return NULL; } if ((p[0][0][0][0]=(void*)malloc(n5*n4*n3*n2*n1*size))==NULL) { free(p[0][0][0]); free(p[0][0]); free(p[0]); free(p); return NULL; } for (i5=0; i5<n5; i5++) { p[i5] = p[0]+i5*n4; for (i4=0; i4<n4; i4++) { p[i5][i4] = p[0][0]+(n4*i5+i4)*n3; for (i3=0; i3<n3; i3++) { p[i5][i4][i3] = p[0][0][0]+ n2*(i3+(n4*i5+i4)*n3); for (i2=0; i2<n2; i2++) p[i5][i4][i3][i2] = (char*)p[0][0][0][0]+ size*n1*(i2+n2*(i3+(n4*i5+i4)*n3)); } } } return p;}/* free a 5-d array */void free5 (void *****p){ free(p[0][0][0][0]); free(p[0][0][0]); free(p[0][0]); free(p[0]); free(p);}/* allocate a 1-d array of ints */int *alloc1int(size_t n1){ return (int*)alloc1(n1,sizeof(int));}/* re-allocate a 1-d array of ints */int *realloc1int(int *v, size_t n1){ return (int*)realloc1(v,n1,sizeof(int));}/* free a 1-d array of ints */void free1int(int *p){ free1(p);}/* allocate a 2-d array of ints */int **alloc2int(size_t n1, size_t n2){ return (int**)alloc2(n1,n2,sizeof(int));}/* free a 2-d array of ints */void free2int(int **p){ free2((void**)p);}/* allocate a 3-d array of ints */int ***alloc3int(size_t n1, size_t n2, size_t n3){ return (int***)alloc3(n1,n2,n3,sizeof(int));}/* free a 3-d array of ints */void free3int(int ***p){ free3((void***)p);}/* allocate a 1-d array of floats */float *alloc1float(size_t n1){ return (float*)alloc1(n1,sizeof(float));}/* re-allocate a 1-d array of floats */float *realloc1float(float *v, size_t n1){ return (float*)realloc1(v,n1,sizeof(float));}/* free a 1-d array of floats */void free1float(float *p){ free1(p);}/* allocate a 2-d array of floats */float **alloc2float(size_t n1, size_t n2){ return (float**)alloc2(n1,n2,sizeof(float));}/* free a 2-d array of floats */void free2float(float **p){ free2((void**)p);}/* allocate a 3-d array of floats */float ***alloc3float(size_t n1, size_t n2, size_t n3){ return (float***)alloc3(n1,n2,n3,sizeof(float));}/* free a 3-d array of floats */void free3float(float ***p){ free3((void***)p);}/* allocate a 4-d array of floats */float ****alloc4float(size_t n1, size_t n2, size_t n3, size_t n4){ return (float****)alloc4(n1,n2,n3,n4,sizeof(float));}/* free a 4-d array of floats */void free4float(float ****p){ free4((void****)p);}/* allocate a 5-d array of floats */float *****alloc5float(size_t n1, size_t n2, size_t n3, size_t n4, size_t n5){ return (float*****)alloc5(n1,n2,n3,n4,n5,sizeof(float));}/* free a 5-d array of floats */void free5float(float *****p){ free5((void*****)p);}/* allocate a 1-d array of doubles */double *alloc1double(size_t n1){ return (double*)alloc1(n1,sizeof(double));}/* re-allocate a 1-d array of doubles */double *realloc1double(double *v, size_t n1){ return (double*)realloc1(v,n1,sizeof(double));}/* free a 1-d array of doubles */void free1double(double *p){ free1(p);}/* allocate a 2-d array of doubles */double **alloc2double(size_t n1, size_t n2){ return (double**)alloc2(n1,n2,sizeof(double));}/* free a 2-d array of doubles */void free2double(double **p){ free2((void**)p);}/* allocate a 3-d array of doubles */double ***alloc3double(size_t n1, size_t n2, size_t n3){ return (double***)alloc3(n1,n2,n3,sizeof(double));}/* free a 3-d array of doubles */void free3double(double ***p){ free3((void***)p);}/* allocate a 1-d array of complexs */complex *alloc1complex(size_t n1){ return (complex*)alloc1(n1,sizeof(complex));}/* re-allocate a 1-d array of complexs */complex *realloc1complex(complex *v, size_t n1){ return (complex*)realloc1(v,n1,sizeof(complex));}/* free a 1-d array of complexs */void free1complex(complex *p){ free1(p);}/* allocate a 2-d array of complexs */complex **alloc2complex(size_t n1, size_t n2){ return (complex**)alloc2(n1,n2,sizeof(complex));}/* free a 2-d array of complexs */void free2complex(complex **p){ free2((void**)p);}/* allocate a 3-d array of complexs */complex ***alloc3complex(size_t n1, size_t n2, size_t n3){ return (complex***)alloc3(n1,n2,n3,sizeof(complex));}/* free a 3-d array of complexs */void free3complex(complex ***p){ free3((void***)p);}#ifdef TESTmain(){ short *hv, **hm; int *iv, **im; float *fv, **fm; double *dv, **dm; size_t i1, i2; size_t n1, n2; scanf("%d %*[^\n]", &n1); scanf("%d %*[^\n]", &n2); /* Exercise 1-d routines */ hv = (short *) alloc1(n1, sizeof(short)); iv = alloc1int(n1); fv = alloc1float(n1); dv = alloc1double(n1); for (i1 = 0; i1 < n1; ++i1) { hv[i1] = i1; iv[i1] = i1; fv[i1] = (float) i1; dv[i1] = (double) i1; } printf("short vector:\n"); for (i1 = 0; i1 < n1; ++i1) { printf("hv[%d] = %hd\n", i1, hv[i1]); } putchar('\n'); printf("int vector:\n"); for (i1 = 0; i1 < n1; ++i1) { printf("iv[%d] = %d\n", i1, iv[i1]); } putchar('\n'); printf("float vector:\n"); for (i1 = 0; i1 < n1; ++i1) { printf("fv[%d] = %f\n", i1, fv[i1]); } putchar('\n'); printf("double vector:\n"); for (i1 = 0; i1 < n1; ++i1) { printf("dv[%d] = %lf\n", i1, dv[i1]); } putchar('\n'); free1(hv); free1int(iv); free1float(fv); free1double(dv); /* Exercise 2-d routines */ hm = (short *) alloc2(n1, n2, sizeof(short)); im = alloc2int(n1, n2); fm = alloc2float(n1, n2); dm = alloc2double(n1, n2); for (i2 = 0; i2 < n2; ++i2) { for (i1 = 0; i1 < n1; ++i1) { hm[i2][i1] = i1 + 2*i2; im[i2][i1] = i1 + 2*i2; fm[i2][i1] = (float) (i1 + 2*i2); dm[i2][i1] = (double) (i1 + 2*i2); } } printf("short matrix:\n"); for (i2 = 0; i2 < n2; ++i2) { for (i1 = 0; i1 < n1; ++i1) { printf("hm[%d, %d] = %hd ", i2, i1, hm[i2][i1]); } putchar('\n'); } putchar('\n'); printf("int matrix:\n"); for (i2 = 0; i2 < n2; ++i2) { for (i1 = 0; i1 < n1; ++i1) { printf("im[%d, %d] = %d ", i2, i1, im[i2][i1]); } putchar('\n'); } putchar('\n'); printf("float matrix:\n"); for (i2 = 0; i2 < n2; ++i2) { for (i1 = 0; i1 < n1; ++i1) { printf("fm[%d, %d] = %f ", i2, i1, fm[i2][i1]); } putchar('\n'); } putchar('\n'); printf("double matrix:\n"); for (i2 = 0; i2 < n2; ++i2) { for (i1 = 0; i1 < n1; ++i1) { printf("dm[%d, %d] = %lf ", i2, i1, dm[i2][i1]); } putchar('\n'); } putchar('\n'); free2(hm); free2int(im); free2float(fm); free2double(dm); exit(0);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -