c++ - std 字符串在类内部损坏

标签 c++ std stdstring

我正在尝试为我想到的一些项目构建一个简单的节点图库,但我很早就遇到了我希望是一个非常简单的障碍,但它让我感到难过。

我定义了称为 NodeDefinitions 的对象,这些对象是可以在预定义配置(端口/参数数量等)中创建节点的方法。 NodeDefinition 对象包含定义每个输入/输出端口的 PortDefinition 对象。这些 PortDefinition 对象包含它们的名称(以及我的完整代码中的一些其他信息,尽管为简洁起见在下面删除了)。

我的 Node 类有一个 Node() 构造函数,它在给定 NodeDefition 对象的情况下创建一个 Node。当我使用它时,我创建了 Port 对象,每个对象都包含一个指向其相应 PortDefinition 的指针。当我尝试打印出端口名称(派生自/存储在 PortDefinition 对象中)时,它已损坏。

通过一些尝试和错误,我设法发现,如果我只是将 std::vector 直接传递给备用 Node() 构造函数,那么一切似乎都可以正常工作。

在下面的示例代码中,我打印出端口名称(这里只有一个端口),既在构造函数中,又在调用者之后。

定义类。

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

所有代码都可以一起编译在一个文件中。

当我运行它时得到以下输出。

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

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

如您所见,当我在使用 Node() 构造函数打印出端口名称时,该构造函数使用 NodeDefinition 对象,名称为空,有时我在那里得到垃圾,这让我觉得有些东西正在以某种方式破坏内存,但我我有点迷失了为什么。

最佳答案

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() 应该可以正常工作,但是 main 中的 print() 现在访问已销毁的拷贝,这是未定义的行为。

一个可能的解决方案是存储 PortDefinitionshared_ptr 或仅在 Port 中存储一个拷贝。

关于c++ - std 字符串在类内部损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47941737/

相关文章:

c++ - native Windows C++ 编程?

c++ - “null-terminated transparent array of elements”中的transparent是什么意思

c++ - 将 Json::Value 转换为 std::string?

c++ - 抛出匿名异常子类

c++ - 将单独的 header 和类定义文件链接到主函数文件-G++返回 “undefined reference to”重载的构造函数

C++编译时断言BASE是EXTENDED的基类并且具有相同的内存地址

python - 通过 std::system 调用 python 时出错

c++ - 删除期间标准容器迭代器失效

c++ - 使用模板编译错误 - 没有匹配的调用函数

c++ - 中断任意等待操作