Heap corruzione - Vector push_back
-
30-09-2019 - |
Domanda
mi sembra di avere un mucchio corrotto, io non riesco a capire perché questo sta accadendo ....
In seguito è la traccia da valgrind ..
==12697== Use of uninitialised value of size 4
==12697== at 0xDD0725: __gnu_cxx::__atomic_add(int volatile*, int) (in /usr/lib/libstdc++.so.6.0.7)
==12697== by 0x1C3AD9BB: chargeRate::chargeRate(chargeRate const&) (in /root//app/libapp++.so)
==12697== by 0x1C4C9C22: __gnu_cxx::__mt_alloc_base<chargeRate>::construct(chargeRate*, chargeRate const&) (mt_allocator.h:585)
==12697== by 0x1C4CAC9F: std::vector<chargeRate, std::allocator<chargeRate> >::_M_insert_aux(__gnu_cxx::__normal_iterator<chargeRate*, std::vector<chargeRate, std::allocator<chargeRate> > >, chargeRate const&) (vector.tcc:284)
==12697== by 0x1C4CAF9E: std::vector<chargeRate, std::allocator<chargeRate> >::push_back(chargeRate const&) (stl_vector.h:610)
==12697== by 0x1C4C8A03: WebTranslations::getChargeDetails(std::vector<std::string, std::allocator<std::string> >&, std::vector<chargeRate, std::allocator<chargeRate> >&) (WebTranslations.cpp:427)
==12697== by 0x1C4C8F83: WebTranslations::getChargeTranslations(std::vector<std::string, std::allocator<std::string> >&, std::vector<std::string, std::allocator<std::string> >&) (WebTranslations.cpp:1172)
==12697==
==12697== Invalid read of size 4
==12697== at 0xDB468B: std::string::string(std::string const&) (in /usr/lib/libstdc++.so.6.0.7)
==12697== by 0x1C3AD9E0: chargeRate::chargeRate(chargeRate const&) (in /root//app/libapp++.so)
==12697== by 0x1C4C9C22: __gnu_cxx::__mt_alloc_base<chargeRate>::construct(chargeRate*, chargeRate const&) (mt_allocator.h:585)
==12697== by 0x1C4CAC9F: std::vector<chargeRate, std::allocator<chargeRate> >::_M_insert_aux(__gnu_cxx::__normal_iterator<chargeRate*, std::vector<chargeRate, std::allocator<chargeRate> > >, chargeRate const&) (vector.tcc:284)
==12697== by 0x1C4CAF9E: std::vector<chargeRate, std::allocator<chargeRate> >::push_back(chargeRate const&) (stl_vector.h:610)
==12697== by 0x1C4C8A03: WebTranslations::getChargeDetails(std::vector<std::string, std::allocator<std::string> >&, std::vector<chargeRate, std::allocator<chargeRate> >&) (WebTranslations.cpp:427)
==12697== by 0x1C4C8F83: WebTranslations::getChargeTranslations(std::vector<std::string, std::allocator<std::string> >&, std::vector<std::string, std::allocator<std::string> >&) (WebTranslations.cpp:1172)
==12697== by 0x1C299E48: zif__get_charge_translations (in /usr/lib/php4/.so)
==12697== by 0x1BCE0916: zend_do_fcall_common_helper (in /usr/lib/httpd/modules/libphp5.so)
==12697== by 0x1BCF1088: zend_do_fcall_handler (in /usr/lib/httpd/modules/libphp5.so)
==12697== by 0x1BCDDD92: execute (in /usr/lib/httpd/modules/libphp5.so)
==12697== by 0x1BCE02A9: zend_do_fcall_common_helper (in /usr/lib/httpd/modules/libphp5.so)
==12697== Address 0xFFFFFFFC is not stack'd, malloc'd or (recently) free'd
==12697==
==12697== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==12697== GPF (Pointer out of bounds?)
==12697== at 0xDB468B: std::string::string(std::string const&) (in /usr/lib/libstdc++.so.6.0.7)
==12697== by 0x1C3AD9E0: chargeRate::chargeRate(chargeRate const&) (in /root//app/libapp++.so)
==12697== by 0x1C4C9C22: __gnu_cxx::__mt_alloc_base<chargeRate>::construct(chargeRate*, chargeRate const&) (mt_allocator.h:585)
==12697== by 0x1C4CAC9F: std::vector<chargeRate, std::allocator<chargeRate> >::_M_insert_aux(__gnu_cxx::__normal_iterator<chargeRate*, std::vector<chargeRate, std::allocator<chargeRate> > >, chargeRate const&) (vector.tcc:284)
==12697== by 0x1C4CAF9E: std::vector<chargeRate, std::allocator<chargeRate> >::push_back(chargeRate const&) (stl_vector.h:610)
==12697== by 0x1C4C8A03: WebTranslations::getChargeDetails(std::vector<std::string, std::allocator<std::string> >&, std::vector<chargeRate, std::allocator<chargeRate> >&) (WebTranslations.cpp:427)
==12697== by 0x1C4C8F83: WebTranslations::getChargeTranslations(std::vector<std::string, std::allocator<std::string> >&, std::vector<std::string, std::allocator<std::string> >&) (WebTranslations.cpp:1172)
Il codice è solo spingendo una struttura in un vettore. La struttura dispone di alcune variabili stringa in esso. Per favore fatemi sapere se è richiesta la fonte per ulteriori debug.
Alcuni fonte:
typedef struct{
string chargeType; // The name of the charge type, eg "Date Units"
string unitSize;
string rate;
bool perConnection;
string cap;
bool useMaxDailyCharge;
string maxDailyCharge;
string identifier;
} chargeRate;
getChargeDetails:
vector<chargeRate> my_vector;
my_vector.push_back(this->getChargeRateDetails(chargeStructureNames[i]));
getChargeRateDetails:
where : vector<vector<string> > StringMatrix
StringMatrix *results; //used to retrive results from database.
chargeRate chargeInformation;
...
//populate results, check them
..
chargeInformation.chargeType = (*results)[FIRST_ROW][CHARGE_TYPE];
return chargeInformation;
Modifica:. Sono consapevole questo sta tornando una "copia" .. questo è test fatto un paio di cose, sto inserendo la stessa in una copia del vettore passato per riferimento
Cheers!
Soluzione
Nel caso in cui getChargeRateDetails
rendimenti di riferimento si sta tentando di utilizzare un riferimento a una variabile che è già fuori del campo di applicazione.
Altri suggerimenti
Sembra che la vostra copia costruttore di non fare la cosa giusta. Al fine di spingere un elemento su un vettore, viene creata una copia del vostro chargeRate
. A prima vista,
at 0xDD0725: __gnu_cxx::__atomic_add(int volatile*, int)
chargeRate::chargeRate(chargeRate const&)
mi dice che i tentativi chargeRate
costruttore di copia per aggiungere qualcosa a una variabile non inizializzata (puntato dall'argomento int volatile*
di __atomic_add
.
Probabilmente, si sta __atomic_add
ing qualcosa a una variabile membro non inizializzato.
StringMatrix *results;
Sembra inteso riferirsi ad una matrice di string
s. Le probabilità sono che il StringMatrix
non è inizializzato bene. Quindi, la prima riga può contenere un inizializzata string
simile pezzo di memoria, che viene utilizzato per copiare costruire il membro chargeType
del nuovo oggetto.
La classe string
contiene un contatore di riferimento che deve essere aumentata quando un nuovi punti string
agli stessi dati, quindi potrebbe avere senso.
È possibile verificare questo (temporaneamente) assegnazione ad esempio una stringa vuota anziché (*results)[FIRST_ROW][CHARGE_TYPE]
.
Non sei sicuro di quello che sta succedendo nella vostra applicazione, ma forse ha a che fare con la (non) usando back_inserter?
v'è un buon esempio qui .