2016-04-26 157 views
-1

有史以來第一篇文章...我試圖讓這段代碼工作,它編譯但是拋出了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(); 
} 

``

+0

向量數據元素的指針可能會在向量容器更改後立即失效。 –

回答

1

讓我們看看這些行:

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

在這裏,您聲明當地變量parametersArrayparameters,然後保存指向這些變量。

當函數返回這些變量超出範圍並且對象被銷燬時。您保存的指針不再指向有效的對象。試圖使用它們將導致未定義的行爲

你有兩種解決方案:或者你不使用指針,而是複製對象(我的建議)。或者你需要動態分配這些對象new(並記住要用delete釋放它們)。

+0

非常感謝你@Joachim Pilerborg你幫了我很多。我結束了使用指針,問題是我沒有爲字符串分配內存。這[後](http://stackoverflow.com/questions/3350385/how-to-return-an-object-in-c)也幫了我很多。 –