返回指向对象的指针向量的指针后,数据会丢失

Data gets lost after returning pointer to vector of pointers to objects

本文关键字:指针 数据 向量 对象 返回      更新时间:2023-10-16

这里有第一篇文章...我正在尝试让这段代码工作,它可以编译但抛出一个 seg。当我在函数返回后尝试使用指针访问数据时出错。我猜函数结束后数据被删除,因此指针丢失。我已经搜索了很多,并认为修复它的唯一方法是如果其他人可以查看我的代码并为我指出正确的方向。提前感谢很多。

/* 
 * Compile with:
 * g++ -std=c++11 -o gsoap_pf_download_config main.cpp soapC.cpp 
 * soapBasicHttpBinding_USCOREIPagaFacilCobroServiceProxy.cpp -lgsoap++ 
 */
#include "soapBasicHttpBinding_USCOREIPagaFacilCobroServiceProxy.h"
#include "BasicHttpBinding_USCOREIPagaFacilCobroService.nsmap"
#include <string>
std::string BVserialNum = "ACF90004";
std::string BVid =        "215";
std::string latitud =     "0";
std::string longitud =    "0";
class SoapClient {
  ns2__ParametrosEnvio *parameters;
  ns2__ArrayOfParametrosEnvio *parametersArray;
  public:
    int downloadConfig();
  private:
    std::string getToken(std::string date, std::string time);
    std::string getProcessKey(std::string token);
    int createClient(_tempuri__AperturaTerminalConsumo &client);
};
int SoapClient::createClient(_tempuri__AperturaTerminalConsumo &client) {
  timeval curTime;
  gettimeofday(&curTime, NULL);
  std::string date = getDate(curTime);
  std::string time = getTime(curTime);
  std::string timeMicro = getTimeWithMicroSecs(curTime);
  std::string token = getToken(date, time);
  std::string processKey = getProcessKey(token);
  ns2__ParametrosEnvio *arrayParam1 = new ns2__ParametrosEnvio(); 
  ns2__ParametrosEnvio *arrayParam2 = new ns2__ParametrosEnvio();
  ns2__ParametrosEnvio *arrayParam3 = new ns2__ParametrosEnvio();
  ns2__ParametrosEnvio *arrayParam4 = new ns2__ParametrosEnvio();
  ns2__ParametrosEnvio *arrayParam5 = new ns2__ParametrosEnvio();
  ns2__ParametrosEnvio *arrayParam6 = new ns2__ParametrosEnvio();
  ns2__ParametrosEnvio *arrayParam7 = new ns2__ParametrosEnvio();
  std::string tokenStr = "TerminalToken";
  std::string processKeyStr = "LlaveProceso";
  std::string serialNumStr = "TerminalSerie";
  std::string dateStr = "TerminalFecha";
  std::string timeStr = "TerminalHora";
  std::string latStr = "Latitud";
  std::string lonStr = "Longitud";
  arrayParam1->Key = &tokenStr;
  arrayParam1->Data = &token;
  arrayParam2->Key = &processKeyStr;
  arrayParam2->Data = &processKey;
  arrayParam3->Key = &serialNumStr;
  arrayParam3->Data = &BVserialNum;
  arrayParam4->Key = &dateStr;
  arrayParam4->Data = &date;
  arrayParam5->Key = &timeStr;
  arrayParam5->Data = &time;
  arrayParam6->Key = &latStr;
  arrayParam6->Data = &latitud;
  arrayParam7->Key = &lonStr;
  arrayParam7->Data = &longitud;
  std::vector<ns2__ParametrosEnvio*  > parametersVector;
  parametersVector.push_back(arrayParam1);
  parametersVector.push_back(arrayParam2);
  parametersVector.push_back(arrayParam3);
  parametersVector.push_back(arrayParam4);
  parametersVector.push_back(arrayParam5);
  parametersVector.push_back(arrayParam6);
  parametersVector.push_back(arrayParam7);
  ns2__ArrayOfParametrosEnvio parametersArray;
  parametersArray.ParametrosEnvio = parametersVector;
  ns2__ParametrosEnvio parameters;
  parameters.ListaDatos = &parametersArray;
  client.Parametros = &parameters;
  int i = 0;
  for (std::vector<ns2__ParametrosEnvio*  >::iterator it = 
    parametersVector.begin(); it != parametersVector.end(); ++it) {
    std::cout << *it << ":" 
    << *client.Parametros->ListaDatos->ParametrosEnvio.at(i)->Key << ":" 
    << *client.Parametros->ListaDatos->ParametrosEnvio.at(i)->Data 
    << std::endl;
    ++i;
  }
  return SOAP_OK;
}
int SoapClient::downloadConfig() {
  BasicHttpBinding_USCOREIPagaFacilCobroServiceProxy service;
  _tempuri__AperturaTerminalConsumo client;
  _tempuri__AperturaTerminalConsumoResponse response;
  createClient(client);
  std::cout << *client.Parametros->ListaDatos->ParametrosEnvio.at(0)->Key << std::endl;
  std::cout << *client.Parametros->ListaDatos->ParametrosEnvio.at(1)->Key << std::endl;
  std::cout << *client.Parametros->ListaDatos->ParametrosEnvio.at(2)->Key << std::endl;
  std::cout << *client.Parametros->ListaDatos->ParametrosEnvio.at(3)->Key << std::endl;
  std::cout << *client.Parametros->ListaDatos->ParametrosEnvio.at(4)->Key << std::endl;
  std::cout << *client.Parametros->ListaDatos->ParametrosEnvio.at(5)->Key << std::endl;
  std::cout << *client.Parametros->ListaDatos->ParametrosEnvio.at(6)->Key << std::endl;
  int ret = service.AperturaTerminalConsumo(&client, response);
  if (ret == SOAP_OK) {
    std::cout << "id:" << *response.AperturaTerminalConsumoResult-> 
    TerminalConsumo->Id << std::endl;
    std::cout << "locality:" << *response.AperturaTerminalConsumoResult-> 
    TerminalConsumo->LocalidadDispositivoId << std::endl;
    std::cout << "route:" << *response.AperturaTerminalConsumoResult-> 
    Ruta->Id << std::endl;
    std::cout << "fare:" << *response.AperturaTerminalConsumoResult-> 
    Ruta->Tarifa << std::endl;
  }
  else
    service.soap_stream_fault(std::cerr);
  service.destroy(); // delete data and release memory
}
int main()
{ 
  SoapClient client;
  client.downloadConfig();
}

''

让我们看一下这些行:

ns2__ArrayOfParametrosEnvio parametersArray;
...
ns2__ParametrosEnvio parameters;
parameters.ListaDatos = &parametersArray;
client.Parametros = &parameters;

在这里,你声明局部变量parametersArrayparameters,然后保存指向这些变量的指针。

当函数返回时,这些变量超出范围,对象被破坏。已保存的指针不再指向有效对象。尝试使用它们将导致未定义的行为

您有两种解决方案:要么不使用指针,而是复制对象(我的建议)。或者你需要用new动态分配这些对象(并记住用delete释放它们)。