Как вернуть двумерный массив символов C ++? - PullRequest
10 голосов
/ 06 апреля 2009

Я создал двумерный массив внутри функции, я хочу вернуть этот массив и передать его куда-нибудь другой функции ..

char *createBoard( ){  
  char board[16][10];
  int j =0;int i = 0;
  for(i=0; i<16;i++){
        for( j=0;j<10;j++){   
                board[i][j]=(char)201;
        }   
  }
  return board;
}

но это продолжает давать мне ошибку

Ответы [ 8 ]

11 голосов
/ 06 апреля 2009

Да, вы видите, что вы возвращаете указатель на объект (массив с именем board), который был создан в стеке. Массив уничтожается, когда он выходит из области видимости, поэтому указатель больше не указывает на какой-либо действительный объект (висячий указатель).

Вам нужно убедиться, что массив выделен в куче, используя new. Освященный метод создания динамически размещаемого массива в современном C ++ заключается в использовании чего-то вроде класса std::vector, хотя здесь это сложнее, поскольку вы пытаетесь создать 2D-массив.

char **createBoard()
{
    char **board=new char*[16];
    for (int i=0; i<16; i++)
    {
       board[i] = new char[10];
       for (int j=0; j<10; j++)
         board[i][j]=(char)201;
    }

    return board;
}

void freeBoard(char **board)
{
    for (int i=0; i<16; i++)
      delete [] board[i];
    delete [] board;
}
11 голосов
/ 06 апреля 2009

Лучший подход - создать класс доски и сделать функцию ctreateBoard его конструктором:

class Board {
  private:
   char mSquares[16][10];

   public:
    Board() {
        for(int i=0; i<16;i++){
        for( int j=0;j<10;j++){   
                mSquares[i][j]=201;
        }       
    }

   // suitable member functions here
 };

Информация о том, как использовать такой класс, ничем не заменит чтение хорошей книги. Я настоятельно рекомендую Ускоренный C ++ от Эндрю Кенига и Барбры Му.

2 голосов
/ 06 апреля 2009

Я бы действительно рекомендовал использовать для этого контейнеры STL vector <> или boost / multi_array.

Если вы должны использовать массивы, я бы порекомендовал использовать typedef для определения массива.

typedef char[16][10] TBoard;

Вы также можете вернуть

 char**

... но тогда вам нужно будет привести его к правильному размеру, чтобы правильно его проиндексировать. C ++ не поддерживает динамические многомерные массивы.

Также, как другие предлагали, вы не можете вернуть объект в стеке (то есть, локальную переменную)

2 голосов
/ 06 апреля 2009

Этот подход не будет работать. Если вы вернете указатель на локальную переменную, вы столкнетесь с неопределенным поведением. Вместо этого выделите массив в куче с помощью new и скопируйте в него данные вручную, проиндексировав его.

1 голос
/ 06 апреля 2009

Не возвращайте указатель на локальную переменную, как уже упоминалось. Если бы я был вынужден сделать то, что вы хотите достичь, сначала я бы пошел на std :: vector. Так как вы не изучили std :: vector, вот другой способ:

void createBoard(char board[16][10])
{  
  int j =0;int i = 0;
  for(i=0; i<16;i++){
        for( j=0;j<10;j++){   
                board[i][j]=(char)201;
        }       
  }
}
0 голосов
/ 06 апреля 2009

Вы не должны возвращать указатель на локальные переменные функции, потому что это пространство перезаписывается, как только функция возвращается.

Хранилище, связанное с платой, находится в стеке функции.

0 голосов
/ 06 апреля 2009

Простой ответ на ваш вопрос: char **.

Сказав это, НЕ ДЕЛАЙТЕ ЭТОГО! Ваша переменная "board" не будет существовать вне createBoard ().

Используйте boost :: multi_array и передайте его как ссылку на createBoard () или верните его напрямую (но если вы это сделаете, он будет скопирован).

0 голосов
/ 06 апреля 2009

Вы должны вернуть char** вместо char*

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