如何为指针和三维数组动态分配内存

时间:2015-08-11 23:54:36

标签: c for-loop multidimensional-array malloc double-pointer

我希望使用malloc动态分配内存,以便我可以使用 for loop 来访问每个数组和数组元素。

我的代码如下所示:

long naxes1[3]  = {1,1,1}, naxes2[3]  = {1,1,1}, naxes3[3]  = {1,1,1}, naxes4[3]  = {1,1,1}; //upto naxes20

另一行代码是:

double *pix1,  *pix2,  *pix3,  *pix4,  *pix5; //upto *pix20

要分配内存,我这样做:

pix1  = (double *) malloc(npixels * sizeof(double));        
pix2  = (double *) malloc(npixels * sizeof(double));//20 times,

我们如何使用for循环为像素分配内存而不是这个?

此外,

#include"cfitsio.h"
long        npixels = 1;
fits_read_pix(names[0], TDOUBLE, firstpix, npixels, NULL, pix1, NULL, &status)

这里,names [i]是fitsfile输入的名称,TDOUBLE是double类型,第一个像素,npixels等是C库例程cfitsio.h中的局部变量

3 个答案:

答案 0 :(得分:2)

当您编写变量名称naxes1naxes2,...,naxes20时,您需要重写代码以使用数组。如果您需要索引1..20,那么您可以写:

int naxes[21][3] = { { -1, -1, -1 },  /* Element 0 - unused */
                     { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 },
                     { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 },
                     { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 },
                     { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 },
                     { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 },
                   };

或者,使用非常明智和方便的GCC extension

int naxes[21][3] = { [0] = { -1, -1, -1 }, [1 ... 20] = { 1, 1, 1 }, };

范围符号[1 ... 20]是扩展名; [0] = { -1, -1, -1 },是标准C99 - 指定的初始化程序。

有了这个,您可以naxes[n][m]使用n范围内的1..20m范围内的0..2来访问{{1}的元素}}

类似的评论适用于naxes变量。但是,你需要动态内存分配;然后你可以使用:

pixN

现在,您可以double *pix_base = malloc(20 * npixels * sizeof(double)); if (pix_base == 0) { …handle out of memory error… } double pix[21]; pix[0] = 0; for (int i = 1; i < 21; i++) pix[i] = pix_base + (i - 1) * npixels; 使用pix[n][m]范围内的n1..20范围内的m来访问数据。完成后,您可以调用0..(npixels-1)一次释放所有内存。这在空间上比20个单独的内存分配更经济(在拨打free(pix_base)malloc()时更经济。)

您也可以调整第二种技术来处理整数数组。

如果您可以使用条目0..19而不是1..20,那么您可以节省一点复杂性。

答案 1 :(得分:1)

您可能会进行大量复制和粘贴以获得该代码。好吧,让我们使用你的系统逻辑,并借助一些2D数组分离出重复的逻辑:

long naxes[20][3];
const long naxes_init[3] = {1, 1, 1};

for (int i = 0; i < 20; ++i)
{
    memcpy(naxes[i], naxes_init, 3 * sizeof (long));
}

double *pix[20];

for (int i = 0; i < 20; ++i)
{
    pix[i]  = (double *) malloc(npixels * sizeof(double));
}

你已经掌握了大部分逻辑:你只需要理解for循环语法。毕竟,第二个循环中的行几乎就是你之前复制过20次的行。

最后,关键的区别在于C当然使用基于0的索引......所以你应该这样做。例如pix[0]相当于您的pix1

答案 2 :(得分:0)

这个怎么样:

double *pix[20];
int i;
for (i=0;i<20;i++) {
    pix[i] = calloc(npixels, sizeof(double));
    if (pix[i] == NULL) {
        perror("calloc failed");
        exit(1);
    }
}

我正在使用calloc而不是malloc,因为前者适合创建数组,并且具有将所有字节初始化为零的副作用。