2017-12-22 1 views
2

일부 프로젝트에 대해 간단한 노드 그래프 라이브러리를 구축하는 실험을하고 있습니다.하지만 아주 초기에 정말 간단한로드 블록이 나오기는하지만 저에게는 어려움이 있습니다.std 문자열이 클래스 내부에서 손상됩니다.

미리 정의 된 구성 (포트 수/매개 변수 수 등)에서 노드를 만들 수있는 레시피 인 NodeDefinitions라는 개체를 정의합니다. NodeDefinition 객체는 각 입력/출력 포트를 정의하는 PortDefinition 객체를 포함합니다. 이러한 PortDefinition 객체에는 이름이 포함되어 있습니다 (간결하게하기 위해 아래에서 제거되었지만 전체 코드의 일부 다른 정보와 함께).

내 Node 클래스에는 NodeDefition 개체가있는 Node를 만드는 Node() 생성자가 있습니다. 이것을 사용할 때 각각 PortDefinition에 대한 포인터를 포함하는 Port 객체를 만듭니다. PortDefinition 객체에서 파생/저장 한 포트의 이름을 출력하려고하면 손상됩니다.

약간의 시행 착오를 통해 나는 대체 Node() 생성자에 std :: vector를 직접 전달하면 모든 것이 올바르게 작동하는 것으로 나타났습니다.

아래의 예제 코드에서는 생성자 내부와 호출자 내에서 모두 포트 이름 (여기에는 하나의 포트만 표시)을 인쇄합니다.

정의 클래스.

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

모든 코드를 하나의 파일로 함께 컴파일 할 수 있습니다.

실행할 때 다음과 같은 결과가 표시됩니다. 내가 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

관련 문제