2009-04-06 13 views
10
私は関数内で2次元配列を作成しまし

、私はその配列を返すようにしたい、と他の関数にどこかにそれを渡す。..2次元のchar配列C++を返す方法は?

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; 
} 

が、これは私にエラー

+0

もっと詳しくエラーが発生しますか? –

+1

201がcharの範囲内にないため、unsigned charを代わりに使用する必要があります。 –

+2

また、ローカル変数のアドレスを返します。アクセスしようとすると、プログラムがクラッシュします。 – Naveen

答えて

11

うん、あなたがスタック上に作成されたオブジェクト(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; 
} 
+0

を生成します.2行目にエラーが表示されます。「 構文エラー:ありません ';' before '[' " – r4ccoon

+0

は、2行目のブラケットを取り除いて動作します。 char ** board =新しいchar * [maxX];少なくともそれは私にコンパイラエラーとアウトバウンドエラーを与えません – r4ccoon

+0

ええ、それは申し訳ありません、私はコンパイラに座っていなかったと私はその行の構文を推測しなければならなかった。 –

0

を与え続けてあなたが代わりにchar**を返す必要がありますchar*

+0

これを行うと、 はグリッド定義を に変更しました。char * board [16] [10]; と* board [i] [j] =(char)201への割り当て; はまだコンパイルエラー – r4ccoon

2

この方法は機能しません。ローカル変数へのポインタを返すと、未定義のビヘイビアが実行されます。代わりにというヒープに配列を割り当て、手動でインデックスを作成してデータをコピーします。

0

あなたの質問に対する簡単な答えはchar **です。

言われているように、しないでください! "board"変数はcreateBoard()の外側にはありません。

使用boost::multi_arrayと(あなたがそれを行う場合は、それがコピーされます)createBoardへの参照()として渡したり、直接それを返します。

+0

申し訳ありませんが、ブーストフレームワークを使用しないでください。それは基本的なC++ – r4ccoon

2

私は本当にSTLベクトル<を使用することをお勧めします>や/このためmulti_arrayコンテナを高めるでしょう。

アレイを使用する必要がある場合は、typedefを使用して配列を定義することをお勧めします。

typedef char[16][10] TBoard; 

また

char** 

を返すことができます...しかし、あなたは正しく、インデックス、それをするために、適切なサイズにそれを型キャストする必要があります。 C++では、動的な複数次元配列はサポートされていません。

また他の人はあなたが(すなわち、ローカル変数)をスタック上のオブジェクトを返すことができません示唆しているよう

+0

傾きの使用のブーストフレームワークを使用すると仮定し、彼らはベクトルについて私を教えるhavent ..だから私はそれを使用することはできません – r4ccoon

+0

その後、静的なボードサイズを持っている場合typedefに行く。 –

0

このスペースは、すぐに関数として上書きされますので、あなたはローカル変数関数へのポインタを返すしてはなりません戻る。

ボードに関連付けられたストレージは、関数のスタック上にあります。

11

最善のアプローチは、ボードのクラスを作成し、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 
}; 

を、良い本を読みに勝るものはありません。 Andrew KoenigとBarbra MooのAccelerated C++を強くお勧めします。

+0

他のクラスの他の関数にどのように渡しますか? – r4ccoon

+0

簡単な方法は、mSquaresをパブリックとしてマークすることです。ボードオブジェクトへの参照を関数に渡します。 –

+4

シンプルだが悪い。 –

1

他に述べたように、ローカル変数へのポインタを返さないでください。あなたが達成したいことを私が強制されたら、まずは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; 
     }  
    } 
} 
+2

は、 "void createBoard(char(&board)[16] [10]);" (配列への参照) – qwerty

+1

qwerty's right:引数を渡し値として定義します。参照渡し、すべて正常に動作します。 – xtofl

+0

両方ともVisual Studio 2008で動作します。私は混乱しています。実装で何が問題になっていますか?配列はどのように値渡しされますか? – Donotalo