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

时间:2015-06-24 18:27:09

标签: c++ pointers object

我对C ++很新,所以请耐心等待。

我会尽力解释我的问题。

我认为下面的代码很简单,可以理解。我有一个对象DF_XML_Table,它有一个字段' name'。我正在创建对象的实例并将值赋给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 =

3 个答案:

答案 0 :(得分:2)

这与您对象的lifetime相关联。 当您在堆栈上定义xmlTbl时,内存不会在堆上分配,而是在堆栈上,并且指向xmlTbl&xmlTbl)的指针实际上在}大括号之后变为无效for loop。

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

答案 1 :(得分:2)

这是因为您创建的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;

答案 2 :(得分:2)

  

为什么这是输出?

tbl[0]->name =

这是因为

DF_XML_Table xmlTbl;

超出范围,将在每个循环迭代中销毁。您将有一个悬空指针,稍后访问它是Undefined Behaviour

您应该选择一个适当的dynamic memory management智能指针存储在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超出范围之前,正确处理以延长其生命时间。< / p>