在循环中填充C++对象字段会导致空字段

Populating C++ object fields inside loop is resulting in empty fields

本文关键字:字段 对象 循环 填充 C++      更新时间:2023-10-16

我对C++还很陌生,所以请耐心等待。

我会尽量简单地解释我的问题。

我认为下面的代码足够简单易懂。我有一个对象DF_XML_Table,它有一个字段"name"。我正在创建对象的实例,并为名称字段指定值。这导致名称字段为空。

vector<DF_XML_Table*> tblVec;
for (int i = 1; i <= 5; i++)
{
    string tblName = "Name";
    DF_XML_Table xmlTbl;
    xmlTbl.name = tblName;
    tblVec.push_back(&xmlTbl);
}
cout << "tbl[0]->name = " << tblVec[0]->name << endl;

为什么这是输出?

tbl[0]->name =

为什么这是输出?

tbl[0]->name =

这是因为

DF_XML_Table xmlTbl;

超出范围,并且将在每个循环迭代中被销毁。您将有一个悬空的指针,稍后访问它是"未定义的行为"。


您应该选择一个适当的动态内存管理智能指针来存储在std::vector<>:中,而不是使用原始指针

vector<std::unique_ptr<DF_XML_Table>> tblVec;
for (int i = 1; i <= 5; i++) {
    DF_XML_Table* xmlTbl = ;
    tblVec.push_back(std::unique_ptr<DF_XML_Table>(new DF_XML_Table()));
    tblVec.back()->name = "Name";
}
cout << "tbl[0]->name = " << tblVec[0]->name << endl;

上面的代码将确保动态分配对象的所有权转移到包含的vector<std::unique_ptr<DF_XML_Table>>,并得到适当的处理,使其寿命不早于tblVec超出范围。

这链接到对象的生存期。当您在堆栈上定义xmlTbl时,内存不是在堆上分配的,而是在堆栈上分配的。在for循环的}大括号之后,指向xmlTbl&xmlTbl)的指针实际上变为无效。

您需要做的是通过使用vector<DF_XML_Table>(而不是vector<DF_XML_Table*>)或使用new来分配内存(但您必须对每个分配的指针调用delete以避免泄漏)来分配这些指针

这是因为您正在创建的xmlTbl对象只存在于for的范围内,一旦它退出for,就会被释放。相反:

vector<std::unique_ptr<DF_XML_Table>> tblVec;
for (int i = 1; i <= 5; i++)
{
    string tblName = "Name";
    tblVec.push_back( unique_ptr<DF_XML_Table>( new DF_XML_Table ) );
    tblVec.back()->name = tblName;
}
cout << "tbl[0]->name = " << tblVec[0]->name << endl;