C ++ Динамическая проблема многомерного массива - PullRequest
0 голосов
/ 10 мая 2011

Я разрабатываю 2d-платформер. Все было хорошо, пока мне не удалось решить проблему. Карта уровней хранится в динамическом многомерном массиве (char ** map). Работает нормально, пока не захочу переопределить

Вот часть кода:

Map& Map::operator=(const Map& rhs)
{
    if(width!=0||height!=0)
    {
        for(int i=0;i<width;i++)
            delete[] map[i];
        delete[] map;
    } //deleting previously created array

    height=rhs.height;
    width=rhs.width; //receiving other map's size

    map=new char* [width];
    walkmap=new unsigned char* [width];
    objmap=new char* [width];
    for(int i=0;i<width;i++)
    {
        *(map+i)=new char[height];
    } //creating new array

    for(int h=0;h<height;h++)
        for(int w=0;w<width;w++)
        {
            map[w][h]=rhs.map[w][h];
        } //receiving new values

    //...
}

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

Ответы [ 2 ]

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

Как всегда, Boost имеет элегантный и экономичный по памяти класс многомерных массивов:

http://www.boost.org/doc/libs/1_39_0/libs/multi_array/doc/user.html

Например, для настройки массива значений bool 10 x 20:

<code> 
    boost::multi_array  mtaFlagMatrix(boost::extents[10][20]);
 

Затем для доступа к его элементам:

<code> 
    mtaFlagMatrix[2][6] = false; // indexes are zero-based - just like normal C arrays
     ...
    if ( mtaFlagMatrix[2][6] )
    {
       ...
    }
 

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

<code> 
typedef boost::multi_array array_type;</p>

<p>array_type::extent_gen extents;
  array_type A(extents[3][3][3]);
  A[0][0][0] = 4;
  A[2][2][2] = 5;
  A.resize(extents[2][3][4]);
  assert(A[0][0][0] == 4);
  // A[2][2][2] is no longer valid.

Это сэкономило мне много времени на тестирование в экстремальных случаях.

0 голосов
/ 10 мая 2011

Ваш 2d массив не освобожден должным образом.Я советую вам использовать способ Iliffe для выделения 2d-массивов, который быстрее и безопаснее использовать:

char** alloc_array( int h, int w )
{
  typedef char* cptr;
  int i;
  char** m = new cptr[h];
  m[0] = new char[h*w];
  for(i=1;i<h;i++) m[i] = m[i-1]+w;
  return m;
}

void release_array(char** m)
{
  delete[] m[0];
  delete[] m;
}

int main()
{
  int r,c;
  char** 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);
}

Это может быть легко инкапсулировано в аккуратный класс 2d-массива или сделано вместо использования std :: vectorсырого распределения.Предпочитайте этот способ создания 2d-массива, поскольку он удобен для кэша, стиль обеспечивает доступ [] [] и не медленнее, а иногда быстрее, чем полиномиальный 1d-доступ.

...