Почему мой 2D-массив вызывает ошибку шины в C? - PullRequest
3 голосов
/ 05 мая 2011

Я пытаюсь создать простой двумерный массив в C, но, видимо, сталкиваюсь с некоторыми проблемами с памятью. Моя настройка достаточно проста, и я не могу сказать, что не так. Я признаю, что мое понимание указателей недостаточно, но я все еще думаю, что это должно работать. Кто-нибудь может увидеть здесь недостаток?

typedef unsigned int DATUM;
DATUM **series_of_data;
void initialize_data()
{
    *series_of_data = (DATUM *) malloc(1024 * sizeof(DATUM));
}

Это приводит к сбою моей программы с ошибкой шины при ее запуске.

Ответы [ 3 ]

6 голосов
/ 05 мая 2011

series_of_data фактически не выделено.

У вас есть различные способы выделения 2D-массива, либо с использованием модели массива строк, которая имеет плохую когерентность кэша и, следовательно, обычно имеет плохую производительность, либо использовать рекомендованный вектор Iliffe.в Числовых рецептах в C, который состоит в выделении одного огромного блока памяти h * w и массива боковых указателей, который содержит начало ваших строк (или столбцов):

DATUM** alloc_array( int h, int w )
{
  int i;
  DATUM** m = (DATUM**)malloc(h*sizeof(DATUM*));
  m[0] = (DATUM*)malloc(h*w*sizeof(DATUM));
  for(i=1;i<h;i++) m[i] = m[i-1]+w;
  return m;
}

void release_array(DATUM** m)
{
  free( m[0] );
  free( m);
}

int main()
{
  int r,c;
  DATUM** tab;
  int width  = 5;
  int height = 3;
  tab = alloc_array(height, width); /* column first */

  for(r = 0;r<height;++r)
   for(c = 0;c<width;++c)
    tab[r][c] = (1+r+c);

  for(r = 0;r<height;++r)
  {
    for(c = 0;c<width;++c)
    {
      printf("%d\t",tab[r][c]);
    }
    puts("");
  }
  release_array(tab);
}

Данные красиво упакованы в памяти, поэтомукеш счастлив, и вы сохраняете шаблон доступа [] [].Скорость зависит от +/- 3% скорости классического метода полиномиального доступа DATUM * +.

1 голос
/ 05 мая 2011

series_of_data - недопустимый указатель - вы никому его не назначаете. Когда вы пытаетесь присвоить его ячейке памяти (*series_of_data = ...), он помещает вещи в случайное место, что, вероятно, не будет делать то, что вы хотите. Вы должны указать series_of_data где-нибудь полезное, например,

series_of_data = (DATUM **)malloc(16 * sizeof(DATUM *))

для массива с 16 слотами для DATUM * указателей в нем.

1 голос
/ 05 мая 2011

Вы не выделили указатель series_of_data до назначения *series_of_data.

Например, если series_of_data предназначен для массива, вам нужно написать что-то вроде этого:

series_of_data = malloc(n*sizeof(DATUM*));

, где n - длина массива series_of_data.

Только после того, как вы это сделаете, вы можете назначить *series_of_data.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...