【问题标题】:how to allocate memory dynamically for pointers and three dimensional arrays如何为指针和三维数组动态分配内存
【发布时间】:2015-11-04 09:27:22
【问题描述】:

我想动态分配内存使用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] 是 fitfile 输入的名称,TDOUBLE 是双精度类型,第一个像素,npixels 等是 C 库例程 cfitsio.h 中的局部变量

【问题讨论】:

  • 你应该只发布整段代码,这样更难理解,例如,你在malloc 中使用的npixles 是什么?
  • 你在问如何设置一个指针数组来加倍吗?

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


【解决方案1】:

这个怎么样:

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

【讨论】:

  • 你为什么会假设它需要初始化为0。如果您要立即对其进行初始化,则充其量只是浪费了对 memset 的调用,并且可能会阻止编译器使用其 malloc 内置函数进行优化。
【解决方案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 — 指定的初始化程序。

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

类似的 cmets 适用于 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 使用pix[n][m],在0..(npixels-1) 范围内使用m 来访问数据。完成后,您调用free(pix_base) 一次释放所有内存。这在空间上比 20 个单独的内存分配更经济(并且在调用 malloc()free() 时更经济)。

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

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

【讨论】:

  • 那么如何释放内存,像这样呢? for (int i = 1; i
  • 我说free(pix_base); naxes 数组是一个自动(或static)数组,不需要释放。
  • 我是这样做的:其中 N = 20; '双 *pix[N]; for (int i=0;i
【解决方案3】:

您可能进行了大量的复制和粘贴来获得该代码。好吧,让我们使用您的系统逻辑并借助一些 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-loop 语法。毕竟,第二个循环中的行几乎与您之前复制 20 次的内容完全相同。

最后,一个关键的区别是当然 C 使用基于 0 的索引......你也应该如此。例如pix[0] 等同于您的pix1

【讨论】:

    猜你喜欢
    • 2017-11-02
    • 2011-09-30
    • 1970-01-01
    • 2015-06-19
    • 2013-10-04
    • 1970-01-01
    • 2019-07-12
    • 2015-02-05
    • 1970-01-01
    相关资源
    最近更新 更多