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

how to allocate memory dynamically for pointers and three dimensional arrays

我想动态分配内存 使用malloc 以便我可以使用for 循环 访问每个数组和数组元素.

我的代码如下所示:

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类型,first pixels,npixels等是C库例程中的局部变量cfitsio.h

这个怎么样:

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,因为前者适合创建数组,并且具有将所有字节初始化为零的副作用。

当你写了变量名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] for n in the range 1..20 and m in the range 0..2 to access the elements of 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;

您现在可以对 1..20 范围内的 n0..(npixels-1) 范围内的 m 使用 pix[n][m] 来访问数据。完成后,调用 free(pix_base) 立即释放所有内存。这在 space 上比 20 个单独的内存分配更经济(并且在调用 malloc()free() 上更经济)。

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

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

您可能进行了大量的复制和粘贴操作才得出该代码。好吧,让我们使用你的系统逻辑,并在一些二维数组的帮助下分离出重复的逻辑:

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.