【问题标题】:Writing a function which creates A Jagged 2D Array of Zeros in C编写一个在 C 中创建锯齿状 2D 零数组的函数
【发布时间】:2019-10-18 22:38:23
【问题描述】:

我需要编写一个函数来创建一个具有不同列数的行的二维数组。这是我尝试过的代码:

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

// program which allocates and returns a 2D int array full of zeros
int** make_zeros_jagged(int rows, int* array){
// dynamically allocate space for array
   int** result = malloc(sizeof(int*)*rows);
  if(result==NULL){
    printf("allocation error\n");
    return NULL;
  }

// dynamically allocate space for each row
  for(int row=0; row<rows;row++){
    // put error handling here
    int cols = (sizeof(array[row])/sizeof(int));
      printf("\n col: %d\n", cols); // ----------> always returns 1  
    result[row]=malloc(sizeof(int)*cols);
      for(int col=0; col<cols; col++){
      result[row][col]= 0;
      printf("%d ", result[row][col]);
    }
      printf("\n");
  }
    return result;
}


// driver code for building array
int main(void){

// declare and build 2d array
    int rows = 3;
    int row1[5] ;
    int row2[4] ;
    int row3[3] ;

    int* array[] = { row1, row2, row3 };
    int** newarray;
    newarray = make_zeros_jagged(3,*array);

  return 0;
}

预期的结果应该是

0 0 0 0 0 
0 0 0 0 
0 0 0

但我的代码返回

0 
0 
0

我想知道是否应该在函数的参数中包含每行的列数?但我也不知道该怎么做。将列数读入数组?还是我的方法也可以?请帮我解决一下这个。谢谢!

【问题讨论】:

  • sizeof(array[row]) == sizeof(int),给定int * array
  • 您似乎将分配作为堆栈变量和通过malloc 进行分配混为一谈。您当前正在尝试分配两者:静态变量在 main 内使用 int row1[5]; 并通过函数中的 malloc。你真的想要哪个:malloc-allocated 数组,或者只是指向main 中静态大小数组的指针数组?
  • @rtoijala OP 使用 rowNarrays 作为 malloc-ed 的“模板”,但无法确定大小。
  • 请注意,您不是在创建“二维数组”,也不是“锯齿状”。您正在创建一个指向一维数组的指针数组,其中一维数组的长度不同。

标签: c multidimensional-array jagged-arrays


【解决方案1】:

您必须拥有数组中每一行的列数。您的代码正在将指针传递给所需长度的数组,但您无法从指针中获取它们的长度。

下面的代码采用行数,加上一个包含每列长度的数组。它分配所需的锯齿状数组,并使用calloc 调用将其初始化为零。

int** make_zeros_jagged_resizable(int rows, int* cols) {
    // Allocate array for pointers.
    int** result = malloc(sizeof(*result) * rows);
    if (result == NULL) {
        printf("allocation error\n");
        return NULL;
    }

    // Allocate each of the rows and fill them with zeros.
    for (int i = 0; i < rows; i++) {
        result[i] = calloc(cols[i], sizeof(*result[i]));

        if (result[i] == NULL) {
            printf("allocation error\n");
            // Free all the already-allocated rows.
            for (int j = 0; j < i; j++) {
                free(result[j]);
            }
            free(result);
            return NULL;
        }
    }

    return result;
}

请注意,上面的代码需要多次调用calloc,这对于大量行可能会很慢。此外,这些行在内存中可能彼此远离。如果您通常遍历整个 2D 数组,最好在一次调用中分配整个 int 块,然后将指针设置为指向该单个块。这样做的缺点是您不能再调整单个行的大小。请参阅下面的代码。

int** make_zeros_jagged(int rows, int* cols) {
    // Allocate array for pointers.
    int** result = malloc(sizeof(*result) * rows);
    if (result == NULL) {
        printf("allocation error\n");
        return NULL;
    }

    // Compute total number of ints.
    size_t total_ints = 0;
    for (int i = 0; i < rows; i++) {
        total_ints += cols[i];
    }

    // Allocate array for ints, and zero it.
    // This assumes that you do not want to resize the rows
    // individually afterwards.
    int* space = calloc(total_ints, sizeof(*space));
    if (space == NULL) {
        printf("allocation error\n");
        free(result);
        return NULL;
    }

    // Fill the pointer array with pointers to the correct
    // parts of the int array.
    size_t pos = 0;
    for (int i = 0; i < rows; i++) {
        result[i] = &space[pos];
        pos += cols[i];
    }

    return result;
}

【讨论】:

    猜你喜欢
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 2015-01-03
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多