Где в этом коде сигфо? - PullRequest
       1

Где в этом коде сигфо?

2 голосов
/ 28 октября 2010

Я считаю, что malloc назначен плохо, почему?

 int ** array;
  int i,j;

  array=malloc(10*sizeof(int *));

  for(i=0; i<10; i++)
    for (j=0;j<10; j++)
        array[i][j]=i*j;

Ответы [ 4 ]

7 голосов
/ 28 октября 2010

У вас есть двумерный массив, поэтому вам нужно выделить достаточно места для хранения 100 элементов. В качестве альтернативы, вам нужно выделить каждый столбец (для каждой строки), прежде чем помещать вещи в эту строку. Я бы сделал последнее только в том случае, если массив представлял собой зубчатый массив с разным количеством элементов в строке.

array=malloc(100*sizeof(int)); 

for(i=0; i<10; i++) 
  for (j=0;j<10; j++) 
    array[i*10+j]=i*j; 

или

array=malloc(10*sizeof(int *)); // rows

for(i=0; i<10; i++) {
  array[i] = malloc(10*sizeof(int));  // columns
  for (j=0;j<10; j++) 
      array[i][j]=i*j;
}
6 голосов
/ 28 октября 2010

это должно быть malloc(10*10*sizeof(int));

. Существует два метода создания двумерных массивов в c: использование непрерывной памяти или использование массива указателей.В первом случае вы malloc 10 * 10 последовательных элементов и доступ осуществляется следующим образом: array[i][j] = *(array + i*10 + j) = array[i*10 + j] (не забывайте, что константы жесткого кодирования - это запах).В другом случае вы malloc 10 элементов типа int*, тогда вы malloc строк в цикле.затем доступ как этот array[i][j] = *(*(array + i) + j)

3 голосов
/ 28 октября 2010

Проблема в том, что ваш массив имеет размер 10x10 = 100 элементов, но вы malloc занимает место только в 10 элементах (кстати, приведенный выше комментарий верен: malloc для sizeof (int), а не sizeof (int *)) поскольку int - это то, что вы на самом деле хотите сохранить в массиве.)

Если вы измените malloc на

malloc(100 * sizeof(int))

, то все будет в порядке.РЕДАКТИРОВАТЬ: Просто заметил, что вы объявляете его как int **.Для такого прямоугольного массива вы можете объявить его как int* и индексировать как (j * 10 + i).В противном случае вам придется распределить по первому измерению malloc, а затем malloc для каждой записи для второго измерения.Это медленно и подвержено ошибкам, поэтому лучше использовать метод j*10+i.

0 голосов
/ 28 октября 2010

Вы выделили память для первого измерения, но не второго.

size_t rows = 10;
size_t cols = 10;
int **array = malloc(sizeof *array * rows); // allocates array of 10 int *
if (array)
{
  size_t i;
  for (i = 0; i < rows; i++)
  {
    array[i] = malloc(sizeof *array[i] * cols); // allocates array of 10 int
    if (array[i])
    {
      size_t j;
      for (i = 0; i < cols; i++)
        array[i][j] = i * j;
    }
  }
}

Обратите внимание, что это не выделяет непрерывный блок памяти; если вам нужно, чтобы все 100 элементов были смежными, у вас есть несколько вариантов:

Вариант 1: выделить 1-D массив и вычислить смещения вручную, как показали несколько других;

Вариант 2: выделить 1-D массив и использовать указатель массива и некоторую магию приведения, чтобы он выглядел как 2-D массив:

#define COLS 10

size_t rows = 10;
size_t cols = COLS;
int *array = malloc(sizeof *array * rows * cols);
int (*parr)[COLS] = (int (*)[COLS]) array;
if (array)
{
  size_t i, j;
  for (i = 0; i < rows; i++)
    for (j = 0; j < cols; j++)
      parr[i][j] = i * j;
}

Недостатком является то, что для объявления указателя необходимо знать, сколько столбцов вы работаете, а для C89 вы должны использовать константное выражение времени компиляции для измерения столбца, что в некоторой степени противоречит цели динамического распределение (использование переменной cols не сработает, если вы не используете компилятор C99).

Вариант 3: Если вы используете C99, вы можете использовать VLA и вообще избегать malloc (и сопровождающего free):

int rows = ROWS;
int cols = COLS;

int array[rows][cols];

for (int i = 0; i < rows; i++)
  for (int j = 0; j < cols; j++)
    array[i][j] = i * j;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...