std 字符串在 class 内损坏
std string gets corrupted inside class
我正在尝试为我想到的一些项目构建一个简单的节点图库,但我很早就遇到了我希望是一个非常简单的障碍,但它让我感到难过。
我定义了名为 NodeDefinitions 的对象,这些对象是可以在预定义配置中创建节点的方法(ports/parameters 等)。 NodeDefinition 对象包含定义每个 input/output 端口的 PortDefinition 对象。这些 PortDefinition 对象包含它们的名称(以及我的完整代码中的一些其他信息,尽管为简洁起见在下面删除)。
我的节点 class 有一个 Node() 构造函数,它在给定 NodeDefition 对象的情况下创建一个节点。当我使用它时,我创建了 Port 对象,每个对象都包含一个指向其相应 PortDefinition 的指针。当我尝试打印出端口名称(在 PortDefinition 对象中派生 from/stored)时,它被损坏了。
通过一些尝试和错误,我设法发现如果我只是将 std::vector 直接传递给备用 Node() 构造函数,那么一切似乎都可以正常工作。
在下面的示例代码中,我打印了端口名称(这里只有一个端口),在构造函数内部和调用程序之后。
定义classes.
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;
};
具体对象classes.
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 );
}
这段代码有问题。 portDefs
是 nodeDefinition.m_portDefinitions
的副本,在构造函数完成时被销毁。但是您使用 Port(&it)
.
存储指向这些对象的指针
构造函数中的 print()
应该可以正常工作,但 main 中的 print()
现在访问已销毁的副本,这是未定义的行为。
一个可能的解决方案是存储您的 PortDefinition
的 shared_ptr
或仅在 Port
.
中存储一个副本
我正在尝试为我想到的一些项目构建一个简单的节点图库,但我很早就遇到了我希望是一个非常简单的障碍,但它让我感到难过。
我定义了名为 NodeDefinitions 的对象,这些对象是可以在预定义配置中创建节点的方法(ports/parameters 等)。 NodeDefinition 对象包含定义每个 input/output 端口的 PortDefinition 对象。这些 PortDefinition 对象包含它们的名称(以及我的完整代码中的一些其他信息,尽管为简洁起见在下面删除)。
我的节点 class 有一个 Node() 构造函数,它在给定 NodeDefition 对象的情况下创建一个节点。当我使用它时,我创建了 Port 对象,每个对象都包含一个指向其相应 PortDefinition 的指针。当我尝试打印出端口名称(在 PortDefinition 对象中派生 from/stored)时,它被损坏了。
通过一些尝试和错误,我设法发现如果我只是将 std::vector 直接传递给备用 Node() 构造函数,那么一切似乎都可以正常工作。
在下面的示例代码中,我打印了端口名称(这里只有一个端口),在构造函数内部和调用程序之后。
定义classes.
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;
};
具体对象classes.
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 );
}
这段代码有问题。 portDefs
是 nodeDefinition.m_portDefinitions
的副本,在构造函数完成时被销毁。但是您使用 Port(&it)
.
构造函数中的 print()
应该可以正常工作,但 main 中的 print()
现在访问已销毁的副本,这是未定义的行为。
一个可能的解决方案是存储您的 PortDefinition
的 shared_ptr
或仅在 Port
.