C-在运行时重塑2D数组

时间:2019-01-01 19:54:39

标签: c arrays

在C中如何在运行时重塑2D数组? 例如,我们最初声明了一个无符号的char数组[20] [500],后来需要对其进行重新整形,例如数组[40] [250]。总内存消耗将(并且必须)始终保持不变(10.000字节)。

限制是新整形的数组必须位于最初声明的确切内存空间地址上。我们无法分配其他空间/我们不确定是否将有任何可用空间(微处理器项目)。 我尝试过用calloc,但最终它变成了香蕉:

unsigned char **my_array; //Global defined

void reshape(unsigned short max_cols, unsigned short max_rows){
    my_array = (unsigned char **) calloc(max_cols, sizeof(unsigned char*));
    for(i = 0; i < max_cols; ++i){
        my_array[i] = (unsigned char **) calloc(max_rows, sizeof(unsigned char));
    }
}

我是C语言的新手,非常感谢您的帮助-谢谢!

2 个答案:

答案 0 :(得分:0)

数组重塑可以通过强制转换来实现:

char (*p)[FirstColumns] = calloc(FirstRows, sizeof *p);
// Test p and handle error if NULL.
char (*q)[SecondColumns] = (char (*)[SecondColumns]) p;

只要底层元素是同一类型,就不会出现任何别名问题。

(时髦的C解释可能会质疑访问SecondColumns的数组,该数组原本是FirstColumns的数组,或其一部分,或者重叠多个,是否违反了别名规则,但实际上并没有通过它们的左值访问,因为它们的左值被转换为指针。我不知道有任何编译器在此类代码上产生问题。)

答案 1 :(得分:0)

因此,您实际上需要一个内存缓冲区,然后您拥有指向该内存缓冲区的不同指针数组。

因此,使用全局变量(丑陋),就像这样:

unsigned char *my_data; // allocate to have enough space, 10000 chars or whatever

unsigned char **my_array; //Global defined

void reshape(unsigned short max_cols, unsigned short max_rows) {
    free(my_array); // don't leak memory

    // no need for cast below
    // also, since array will be initialized below, use malloc
    my_array = malloc(max_cols * sizeof(unsigned char*)); 

    // initialize my_data with addresses of rows
    for(i = 0; i < max_cols; ++i) {
        my_array[i] = &(my_data[i * max_rows]);
    }
}

尽管请注意,除非您真的需要my_array作为指针数组,否则可以通过这样直接访问mydata来避免间接访问:

my_data[row_index * max_cols + column_index]