2016-04-26 3 views
-1

первое сообщение здесь ... Я пытаюсь заставить этот код работать, он компилируется, но выдает seg. когда я пытаюсь получить доступ к данным с помощью указателя после возвращения функции. Я думаю, данные удаляются после завершения функции, чтобы утерялся указатель. Я много искал и думал, что единственный способ исправить это - если кто-то еще может взглянуть на мой код и указать мне в правильном направлении. Thanx много вперед.Данные теряются после возврата указателя на вектор указателей на объекты

/* 
* 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(); 
} 

``

+0

Указатели на векторные элементы данных могут быть аннулированы, как только векторный контейнер будет изменен. –

ответ

1

Давайте посмотрим на эти строки:

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

Здесь объявляются локальные переменныеparametersArray и parameters, затем сохранить указатели на эти переменные.

Когда функция возвращает эти переменные, выходят из сферы действия и объекты разрушаются. Указатели, которые вы сохранили, больше не указывают на действительные объекты. Попытка использовать их приведет к не определено поведение.

У вас есть два решения: либо вы не используете указатели, но копируете объекты вместо этого (моя рекомендация). Или вам нужно динамически выделять этот объект с помощью new (и не забудьте освободить их с помощью delete).

+0

Большое вам спасибо @Joachim Pilerborg, что вы мне очень помогли. Я закончил использование указателей, и проблема заключалась в том, что я не выделял память для строк. Этот [post] (http://stackoverflow.com/questions/3350385/how-to-return-an-object-in-c) также очень помог мне. –

Смежные вопросы