在运行时声明全局连续的2d数组。在编译时C,维度是未知的

时间:2015-12-12 12:28:31

标签: c dynamic allocation contiguous

我想在C中声明一个全局2d数组,并在运行时分配连续内存,因为次要维度在编译时是未知的。 我想用2索引符号A [i] [j]取消引用数组。 如果数组不是全局c99表示法“double A [m] [n]”会很方便,但在我的情况下不适用。 什么是正确的策略?

#include <stdio.h>
#include <stdlib.h>

//TO DO
//DECLARE array here

void fun1() {
    array[3][2] = 42.0;
}

int main(int argc,char *argv[])
{
    int rows = atol(argv[1]);
    int cols = atol(argv[2]);

    //TO DO
    //Allocate memory for array here
    fun1();
    printf("Array[3][2]=%f\n",array[3][2]);

    return(0);
}

2 个答案:

答案 0 :(得分:1)

不幸的是,在C中实现你所要求的不太可能。

宏观上有一个稍微丑陋的解决方案。由于宏引用全局数组本身和包含其第二维的全局变量,因此必须小心不要在使用宏的任何函数中遮蔽全局变量。在这里,我使用以下划线结尾的笨重名称来试图避免名称重用。

除此之外,它应该有效:

void*  global_array_void_;
size_t global_array_minor_dim_;

#define global_array ((double(*)[global_array_minor_dim_])global_array_void_)    

在使用宏之前,需要分配它并初始化全局变量:

void init_global_array(int rows, int cols) {
    global_array_minor_dim_ = cols
    global_array_void_ = malloc(rows * cols * sizeof global_array[0][0]);
}

从那时起,您可以像使用常规数组一样使用global_array

void f(int r, int c, double v) {
    global_array[r][c] = v;
}

Live on coliru

演员((double (*)[cols])(array_void_))中的类型可能并不明显。它表示指向cols double s数组的指针,double[][cols]将衰减为指针。请注意,double[][cols] 会衰减到double**,这是一种完全不同(且不兼容)的类型。

根据该定义,sizeof global_array[r]具有正确的值:cols * sizeof(double)。与sizeof argv[i]对比。

更传统的方法是使用函数来计算精确的索引。这仍然取决于可用的次要维度:

double* global_array;
size_t global_array_minor_dim_;

void init_global_array(int rows, int cols) {
    global_array_minor_dim_ = cols
    global_array_void_ = malloc(rows * cols * sizeof global_array[0][0]);
}

double* global_array_at(int r, int c) {
    return &global_array[r * global_array_minor_dim_ + c];
}

现在,您可以使用*global_array_at(r, c)替代global_array[r][c]。在C中,不可能消除*并且仍然具有赋值工作(在C ++中,函数可能返回double&而不是double*),但这可以解决,一次再次,用宏。

答案 1 :(得分:-2)

以下是您可以遵循的示例:

#include <stdlib.h>
void main(void)
{
    int **f;
    int n = 2, m = 3;

    f = (int **)malloc(sizeof(int)*n *m);

    f[1][2] = 3;
}