2017-12-22 15 views
2

私は心に留めているプロジェクトのための単純なノードグラフライブラリを構築することを実験していますが、私は非常に早い段階で本当に単純なロードブロッキングを望んでいます。std stringがクラス内で壊れてしまう

私はノードを事前定義された構成(ポート数/パラメータの数など)で作成できるレシピであるNodeDefinitionsというオブジェクトを定義します。 NodeDefinitionオブジェクトには、各入出力ポートを定義するPortDefinitionオブジェクトが含まれています。これらのPortDefinitionオブジェクトには、名前が記載されています(私のフルコードの他の情報とともに、簡潔にするために以下では削除されています)。

My NodeクラスにはNodeDefitionオブジェクトがあるNodeを作成するNode()コンストラクタがあります。これを使用すると、それぞれに対応するPortDefinitionへのポインタを含むPortオブジェクトが作成されます。ポートの名前(PortDefinitionオブジェクトから派生/格納されている)の名前を印刷しようとすると、破損します。

少し試行錯誤しながら、私はstd :: vectorを代わりのNode()コンストラクタに直接渡すだけですべてが正常に動作するように見えます。

下記のコード例では、コンストラクタの内側と呼び出し側の両方のポート名(ここでは1つのポートのみ)を出力します。

定義クラス。

class PortDefinition 
{ 
public: 
    PortDefinition(const std::string & name) : m_name(name) 
    {} 
    std::string m_name; 
}; 

class NodeDefinition 
{ 
public:  
    NodeDefinition(std::vector<PortDefinition> portDefinitions) : 
     m_portDefinitions(portDefinitions) 
    {} 
    std::vector<PortDefinition> m_portDefinitions; 
}; 

具体的なオブジェクトクラス。

class Port 
{ 
public: 
    Port(PortDefinition * portDefinition) : 
     m_portDefinition(portDefinition) 
    {} 
    const PortDefinition * m_portDefinition; 
}; 

class Node 
{ 
public: 
    Node(NodeDefinition nodeDefinition) { 
     std::vector<PortDefinition> portDefs = nodeDefinition.m_portDefinitions; 
     for (auto & it : portDefs) { 
      Port newPort = Port(&it); 
      m_ports.push_back(newPort); 
     } 
     print(); 
    } 

    Node(std::vector<PortDefinition> portDefs) { 
     for (auto & it : portDefs) { 
      Port newPort = Port(&it); 
      m_ports.push_back(newPort); 
     } 
     print(); 
    } 

    void print() const { 
     std::cout << m_ports.size() << " : "; 
     for (auto it : m_ports) { 
      std::cout << "'" << it.m_portDefinition->m_name << "'" << std::endl; 
     } 
    } 
private: 
    std::vector<Port> m_ports; 
}; 

テストコードです。

int main (int argc, const char *argv[]) 
{  
    std::vector<PortDefinition> portDefinitions; 
    portDefinitions.push_back(PortDefinition("Port_A")); 
    NodeDefinition nodeDefinition = NodeDefinition(portDefinitions); 

    std::cout << "constuctor N1 : "; 
    Node N1 = Node(nodeDefinition); 
    std::cout << "main func N1 : "; 
    N1.print(); 

    std::cout << std::endl; 

    std::cout << "constuctor N2 : "; 
    Node N2 = Node(portDefinitions); 
    std::cout << "main func N2 : "; 
    N2.print(); 
    return 1; 
} 

すべてのコードを1つのファイルでまとめてコンパイルできます。

これを実行すると、次の出力が表示されます。私はNodeDefinitionは名前が空のオブジェクトを使用してノード()コンストラクタを使用した後、ポート名をプリントアウトするときに時々私は私が何かがメモリを破損さと思わせるこれ、そこの代わりにゴミを取得し、見ることができるように

constuctor N1 : 1 : 'Port_A' 
main func N1 : 1 : '' 

constuctor N2 : 1 : 'Port_A' 
main func N2 : 1 : 'Port_A' 

どういうわけか、なぜ私は少し迷っています。

答えて

4
 std::vector<PortDefinition> portDefs = nodeDefinition.m_portDefinitions; 
    for (auto & it : portDefs) { 
     Port newPort = Port(&it); 
     m_ports.push_back(newPort); 
    } 

このコードは問題です。 portDefsnodeDefinition.m_portDefinitionsのコピーで、コンストラクターの終了時に破棄されます。しかし、これらのオブジェクトへのポインタはPort(&it)で保存します。

コンストラクタのprint()は正常に動作するはずですが、メインのprint()が破壊されたコピーにアクセスするようになりました。これは未定義の動作です。

PortDefinitionshared_ptrを保存するか、コピーをPortに保存してください。

+0

もちろんありがとうございます。 shared_ptrで魅力的に動作します。 – Lee

関連する問題