2012-02-13 11 views
1

このプログラムはC++で書かれています。私はvoid関数を使用して整数長さと次の接続された行へのポインタで構成されるLine構造体を拡張しようとしています。構造体内の行ポインタに行参照を割り当てるためのvoid Expand関数があります。新しい行は、現在の行の2倍の大きさでなければなりません。私が使用しているコードでは、「一時的なアドレスを取る」というg ++のエラーが出ます。誰も関数がライン参照nextLineにライン参照の有効なインスタンスを追加する方法を提案することができますか?C++ポインタへの参照を割り当てる際の一時エラーのアドレスを取る

struct Line 
{ 
    int length; 
    Line* nextLine; 
}; 

Line NewLine(Line& lineRef) 
{ 
    Line newLine; 
    newLine.length = lineRef.length * 2; 
    return newLine; 
} 

void Expand(Line& lineRef) 
{ 
    //Error here states: Taking address of temporary [-fpermissive] 
    lineRef.nextLine = &NewLine(lineRef); 
} 

int main() { 

    Line line; 

    Expand(line); 

    cout << line.length << endl; 
    cout << line.nextLine->length << endl; 

    return 0; 
} 

答えて

1

この1つは

struct Line 
    { 
      int length; 
      Line* nextLine; 
      ~Line(){delete nextLine;} 
      //Make copy constructor and assignment operator private 
    }; 

    void Expand(Line* lineRef) 
    { 
      lineRef->nextLine = new Line; 
      lineRef->nextLine->length = 2*(lineRef->length) ; 
    } 

int main() 
{ 

     Line* line = new Line; 
     line->length = 5; 

     Expand(line); 

     cout << line->length << endl; 
     cout << line->nextLine->length << endl; 

     delete line; 
     return 0; 
} 
+0

お願いします...しないでください!これは動作しません。このおもちゃのサンプルでは動作するように見えますが、 'Line'をコピーすると、' nextLine'ポインタがコピーされ、ポインタが指し示すコンテンツはコピーされないので、ひどくクラッシュし、ランタイムは 'delete'同じポインタを2回繰り返します。 –

+0

何が問題なのですか? – sank

+0

はい、コピーコンストラクタと代入演算子はディープコピーを作成するか、プライベートにする必要があります。 – sank

3

回線に問題:

lineRef.nextLine = &NewLine(lineRef); 

は、コンパイラがあなたを語っているものです。あなたは一時的なアドレスを取得しています。つまり、;に達すると、NewLine(lineRef)の一時的な要素が破棄され、ポインタlineRef.nextLineが死んだオブジェクトへのポインタになります。


更新:それを動作させる方法。

あなたのやりたいことによって異なります。あなたが望むものがリストを持っているならば、もっとも簡単なのは、リストの独自の実装をローリングするのではなく、あらかじめパックされたlistデータ構造(std::list<Line>)を使用することです。

実際に独自のリストを実装したい場合は、次のノードを動的に割り当てる必要があります(コンパイラを幸せにする)。にコードを追加する必要があります。リストコピー建設、動的メモリを管理するためのデストラクタ、徒歩リストに、おそらくいくつかのヘルパー関数(またはイテレータ ...アルゴリズムを使用することができるようにする)を含むフィールドを、初期化Lineオブジェクトだけでありませんお気遣いください。std::list

+0

OPはまた、コードの仕事を作る方法を尋ねた作品。 –

+1

私はむしろ、 'list'よりも基本的なデータ構造として' vector'を推奨したいと思います。 –

3

あなたはインプラントしようとしていますリンクされたリストを作成することはできますが、まだ手作業によるメモリ管理については理解していません。

短期的な解決策は、std::list<Line>を使用することです。すでに機能しているソリューションがあります。背後にあるものを気にする必要はありません。

長期的な解決策は、std::list<Line>を使用することです。あなたが熟練した開発者であり、どのように知っていても、ホイールを再発明する必要はありません。

+0

私はむしろ 'list'より基本的なデータ構造として' vector'を推奨したいと思います。 –

+0

@MatthieuM .:なぜ...?質問にあるコードスニペットから推測できないパフォーマンス要件がない場合、list <>はvector <>と同じくらい良いコンテナです。 – Darryl

+0

@Darryl:Stroustrupがそう言ったので? 'vector'はコンテナのデフォルトの*選択です。別のデータ構造を示す要件がない限り、 'vector'を使用してください。それは使いやすく、Sequenceコンテナの中で最高のC互換性を備えています(初心者にとっては重要なことですが、残念なことにチュートリアルではしばしばC-ismsが厄介です...) –

関連する問題