如何为指针和三维数组动态分配内存
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
,因为前者适合创建数组,并且具有将所有字节初始化为零的副作用。
当你写了变量名naxes1
、naxes2
、…、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
范围内的 n
和 0..(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
.
我想动态分配内存 使用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
,因为前者适合创建数组,并且具有将所有字节初始化为零的副作用。
当你写了变量名naxes1
、naxes2
、…、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
范围内的 n
和 0..(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
.