Как выделить массив 2 D с заурядной памятью? Как использовать его для доступа к строкам и столбцам? Приведите пример

Я создал массив 2 d, который читается следующим образом

int i,j,lx,ly;// lx,ly are the row and column respectively double** a; a=(double**) malloc((lx+2)*sizeof(double)); a[0]= (double*) malloc((lx+2)*(ly+2)* sizeof(double)); assert(a[0]); for(i=1;i<lx+2;i++) { a[i]=a[i-1]+i*(ly+2); } 

// Я выделяю значение 0 для всех элементов в этом массиве, как показано ниже

  for(i=0;i<(lx+2)*(ly+2);i++) { a[i]=0; } 

// Я распечатываю все свои элементы ниже

  for(i=0;i<(lx+2)*(ly+2);i++) { printf("position %d values %d\n",i,a[i]); } 

// Когда я вижу вывод, он показывает мне значение нежелательной почты в одном конкретном месте 13. Я не могу это понять .. Также любезно скажите мне, как обращаться к строкам и столбцам, например Eg, для доступа к 7-й строке столбца 0 и 5 строка 6-го столбца в терминах lx, ly, как показано в моем коде

    Ваш подход определенно движется в правильном общем направлении.

    Я думаю это:

     a=(double**) malloc((lx+2)*sizeof(double)); 

    обычно будет:

     a = malloc(lx * sizeof(double *)); 

    И тогда без требования соприкосновения это:

     a[0]= (double*) malloc((lx+2)*(ly+2)* sizeof(double)); 

    в большинстве программ будет выглядеть так:

     a[0] = malloc(ly * sizeof(double)); 

    И, наконец, эта последняя строка должна быть в цикле, который присваивает каждому a[i] собственное пространство malloc’.

    Однако это не приведет к созданию непрерывной памяти. Для этого вам нужно будет сделать это большое выделение, а затем разделите его на вектор строки. Итак, вместо второго malloc в цикле, возможно, что-то вроде:

     double *t = malloc(lx * ly * sizeof(double)); for (i = 0; i < lx; ++i) a[i] = t + i * ly; 

    Объединяя все это:

     #include  #include  void arrayDemo(int lx, int ly) { double **a; int i, j; a = malloc(lx * sizeof(double *)); double *t = malloc(lx * ly * sizeof(double)); for(i = 0; i < lx; ++i) a[i] = t + i * ly; for(i = 0; i < lx; ++i) for(j = 0; j < ly; ++j) a[i][j] = i*100 + j; for(i = 0; i < lx; ++i) { for(j = 0; j < ly; ++j) printf(" %4.0f", a[i][j]); printf("\n"); } } int main(int ac, char **av) { arrayDemo(atoi(av[1]), atoi(av[2])); return 0; } $ cc -Wall all.c $ ./a.out 4 7 0 1 2 3 4 5 6 100 101 102 103 104 105 106 200 201 202 203 204 205 206 300 301 302 303 304 305 306 

    Этот код выделяет 10 на 5 непрерывных блоков памяти, инициализирует его с увеличивающимися удвоениями, а затем печатает значения, индексированные по x и y:

     #include "2d.h" int main(void){ unsigned int x,y; const unsigned int width = 10; const unsigned int height = 5; //we need an index into the x of the array double * index[width]; //need the memory to store the doubles unsigned int memorySizeInDoubles = width * height; double * memory = malloc(memorySizeInDoubles * sizeof(double)); //initialize the memory with incrementing values for(x = 0; x < memorySizeInDoubles; ++x){ memory[x] = (double) x; } //initialize the index into the memory for(x = 0; x < width; ++x){ index[x] = memory + height * x; } //print out how we did for(x = 0; x < width; ++x){ for(y = 0; y < height; ++y){ printf("[%u, %u]: Value = %f\n", x, y, index[x][y]); } } free(memory); return 0; } 

    Файл 2d.h должен содержать следующие строки:

     #include  #include  int main(void); 

    Примечание. Созданная память является лишь смежной для некоторых определений. Память логически соприкасается, но не обязательно физически соприкасается. Если эта память предназначена для драйвера устройства, например, malloc не будет работать.

    Либо вы создаете один размерный массив

     double my_array = malloc(sizeof(double) * size_x * sizeof(double) * size_y); 

    к которому вы

    (получить положение x = 28, y = 12)

     my_array[12 * size_x + 28]; 

    или вы создаете 2d-массив, как вы, но вы обращаетесь к нему с

     double **my_array = (double**) malloc(15 * sizeof(double)); for(int i = 0 ; i < 25; i++) { my_array[i] = (double*) malloc(30 * sizeof(double)); for (int j = 0 ; j < 12; j++) { my_array[i][j] = 1.2; } } double my_double = my_array[12][28]; 

    В C, чтобы иметь один кусок непрерывной памяти, вам нужен один malloc() или иметь статически выделенный массив. Поскольку вам нужна динамическая память, вам понадобится malloc() . Поскольку вам нужно, чтобы все было смежным, вам понадобится только один вызов.

    Теперь, как должен выглядеть звонок? Если вы правильно поняли, вам нужны значения lx times ly , каждый из которых имеет размер sizeof(double) , поэтому вам нужно выделить lx*ly*sizeof(double) байты.

    Отступление: я предпочитаю писать свои вызовы malloc() следующим образом:

     #include  /* for malloc's prototype */ T *pt; /* for any type T */ size_t n; /* need n objects of type T */ pt = malloc(n * sizeof *pt); 

    Использование sizeof с sizeof *pt вместо sizeof(T) дает преимущество в том, что если тип pt изменяется, вам не нужно менять вызов malloc() . Не выдавать результат malloc() хорошо, потому что тогда весь вызов malloc() является агностиком типа, и его легче вводить и читать. Убедитесь, что #include .

    Итак, чтобы выделить пространство для n double s, вы можете сделать:

     double *pd = malloc(n * sizeof *pd); if (pd != NULL) { /* malloc succeeded */ } else { /* malloc failed */ } 

    Теперь, выделив память, вы должны иметь возможность индексировать ее. Допустим, у вас есть lx == 2 и ly == 3 . Ваша память выглядит так:

      +---+---+---+---+---+---+ pd: | 0 | 1 | 2 | 3 | 4 | 5 | +---+---+---+---+---+---+ 

    pd[0] , pd[1] и pd[2]double значения, соответствующие первой строке, pd[3]pd[6] – это double значения, соответствующие второй строке. Вы должны иметь возможность обобщить это наблюдение, чтобы перевести заданную пару x,y index в одно число, которое правильно индексируется в ваш массив pd .