gpt4 book ai didi

具有奇怪行为的 C++ std::vector push_back

转载 作者:行者123 更新时间:2023-11-28 04:04:45 24 4
gpt4 key购买 nike

首先,我对 C 和 C++ 比较陌生,我更习惯于 C#。

基本上,我有一个 vector ,一个名为 CTe 的对象,这个对象有几个变量和一个名为 NFe 的另一个对象的 vector ,我想要填充 CTes 对象的所有信息都存储在一个二维字符串 vector 中,所以这个循环的目标是遍历 vector 的所有行,每行一个 CTe,这个 CTe 可能有一个或多个 NFes 附加到它。

    /*The declaration of the vectors, just to help visualize the structure
vector < string > dirlist;
vector < vector < string > > listElement;
vector < CTe > ctes;*/

//This will iterate through the 2D vector
for (int i = 1; i < listElement.size(); i++)
{
//Temporally CTe object to store information
CTe temp;

string targetCNTR = listElement[i][6];
int countNFE = 0;
bool haveFoundReference = false;

// This will iterate reading all the xmls I have in a folder
for (int j = 2; j < dirlist.size(); j++)
{
string extraInfoNFE = ReadXML(dirlist[j], "infAdic", "infCpl");

//Check if a valid xml was found.
if (extraInfoNFE.find(targetCNTR) != string::npos)
{
haveFoundReference = true;

string sColeta = "000"+listElement[i][3];
stringstream tipoNumber (listElement[i][4]);

//Fill the variables of the temp object
temp.cntr = targetCNTR.c_str();
temp.booking = listElement[i][0].c_str();
temp.motorista = listElement[i][1].c_str();
temp.placas = listElement[i][2].c_str();
temp.coleta = sColeta.c_str();
temp.seqEndereco = listElement[i][5].c_str();
tipoNumber >> temp.tipoCTE;

listElement[i][8+countNFE] = ReadXML(dirlist[j], "ide", "nNF");

//Create a temporally object to store the NFe information
NFe tempNFe;

//Fill the tempNFe object
stringstream nfeNumber (listElement[i][8+countNFE]);
nfeNumber >> tempNFe.numeroNFE;

string sXML = dirlist[j].substr(5, 43);
tempNFe.codigoXML = sXML.c_str();

string sDest = ReadXML(dirlist[j], "dest", "xNome");
tempNFe.destinatario = sDest.c_str();

stringstream cfopNumber (ReadXML(dirlist[j], "det", "prod", "CFOP"));
cfopNumber >> tempNFe.cfop;

stringstream qtdeNumber (ReadXML(dirlist[j], "transp", "vol", "qVol"));
qtdeNumber >> tempNFe.qtde;

stringstream valorNumber (ReadXML(dirlist[j], "total", "ICMSTot", "vNF"));
valorNumber >> tempNFe.valor;

stringstream pesoNumber (ReadXML(dirlist[j], "transp", "vol", "pesoB"));
pesoNumber >> tempNFe.pesoBruto;

//push_back the tempNFe into the temp object
//This part is working perfectly
temp.notas.push_back(tempNFe);
countNFE++;
}
}

//Check if a valid xml was found, if so push_back
//The temp object into the ctes object
//HERE LIES THE PROBLEM
if (haveFoundReference)
{
cout<<temp.cntr<<" - ";
ctes.push_back(temp);
}
else
{
cout << "Não foi possível localizar a nota do CNTR " <<targetCNTR;
}
}

问题是,ctes vector 中的所有 CTe 对象都是相同的,唯一起作用的是 CTe 中的 NFe vector 。

这是 CTe 和 NFe 类:

非金融实体

class NFe
{
public:
NFe();
const char* codigoXML;
const char* destinatario;
int numeroNFE;
int cfop;
int qtde;
float valor;
float pesoBruto;
~NFe();
};

CTE

#include <nfe.h>
#include <vector>

class CTe
{
public:
CTe();
const char* motorista;
const char* placas;
const char* booking;
const char* cntr;
const char* seqEndereco;
const char* coleta;
int espelho;
int tipoCTE;
std::vector < NFe > notas;
virtual ~CTe();
};

最佳答案

正如我之前在评论中提到的,c_str() 返回的char * 仅在相应的字符串对象被销毁或修改之前有效。在你的情况下,

string targetCNTR = listElement[i][6];

在 vector 中创建字符串的拷贝,并在退出 for 循环后立即销毁该拷贝。所以

temp.cntr = targetCNTR.c_str();

一旦 targetCNTR 在退出作用域后被销毁,它就无效。

如果您无法修改类定义以将 const char * 更改为 std::string 并且如果 vector listElement 在整个过程中保持有效在程序的生命周期内,您可以通过获取对实际字符串的引用来修复代码,如下所示

string &targetCNTR = listElement[i][6];

这样,只要 listElement vector 未被破坏或修改,返回的 c_str() 就会有效。如果 istElement 被修改/销毁(您没有提供填充 listElement 的代码,所以它不明显),您还可以创建 char * 的拷贝像这样

/* allocate a new char * on heap */
char *cntr = new char [strlen(targetCNTR.c_str()) + 1];
/* copy the c string */
strcpy(cntr, targetCNTR.c_str());
/* move the char * to desired object */
temp.cntr = cntr;

您可以对所有 char * 变量执行相同的操作。如果您使用这种方法,请记住在类析构函数中释放 char *。例如,

class CTe
{
public:
CTe();
const char* motorista;
const char* placas;
const char* booking;
const char* cntr;
const char* seqEndereco;
const char* coleta;
int espelho;
int tipoCTE;
std::vector < NFe > notas;
virtual ~CTe() {
/* free char * */
delete [] motorista;
delete [] placas;
delete [] booking;
delete [] cntr;
delete [] seqEndereco;
delete [] coleta;
}

};

关于具有奇怪行为的 C++ std::vector push_back,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58945605/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com