Используя только указатели и malloc, как определить массив 2D int? мой, кажется, не работает. (ошибка сегмента) - PullRequest
1 голос
/ 07 июня 2019

Я хочу объявить 2D-массив в .h файле без заданных номеров COLS или ROWS (потому что они читаются где-то из main())

Я имею в виду, я мог бы попробовать другой способ сделатьэто как ниже, если один из ROWS и COLS дан из первых уст.

int COLS = 20;
int (*array)[COLS];
array = malloc((*array) * ROWS); 

таким образом, я попытался, как показано ниже:

ниже - 2 д.ч

int* a;
int** b;
int size; 

ниже - test2d.c,inside int main () {}

read_size() //size value read from some file
a = malloc(sizeof(int) * size);
b = malloc(sizeof(*a) * size);

for(int i=0; i<size; i++){  
  for(int j=0; j<size; j++){   
    b[i][j] = i+j;   
    printf("ok");  
  }
}

//print all

должен печатать все 0112, но результат будет segmentation fault.

Ответы [ 2 ]

3 голосов
/ 07 июня 2019

Чтобы выделить 2D массив, вам нужно выделить 2D указатель b, что вы и сделали. После этого вам нужно выделить память для b[i] в цикле for, как показано ниже

// cols and rows are input by user or other parts of program.
int **b;
b = malloc(sizeof(int*) * rows);

for(int i=0; i<rows; i++){  
    b[i] = malloc(sizeof(int) * cols);
}

Объяснение этому заключается в том, что b - это массив указателей на int. В каждом элементе b вы выделяете массив int. Это дает вам двумерный массив.

0 голосов
/ 07 июня 2019

Если вам нужен прямоугольный (не зубчатый массив), наиболее эффективно выделить все ячейки как один блок, тогда указатели строк могут указывать на этот блок:

#include <stdlib.h>

int **make_array(size_t height, size_t width)
{
    /* assume this multiplication won't overflow size_t */
    int *cells = malloc((sizeof *cells) * height * width);
    int **rows = malloc((sizeof *rows) * height);
    if (!rows || !cells) {
        free(cells);
        free(rows);
        return 0;
    }
    /* now populate the array of pointers to rows */
    for (size_t row = 0;  row < height;  ++row) {
        rows[row] = cells + width * row;
    }
    return rows;
}

Это также делаетосвобождение намного проще, так как нам больше не нужен цикл:

void free_array(int **a)
{
    if (!a) return;
    free(a[0]);
    free(a);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...