cerbert
11-06-2012, 12:59
Premetto che, all'urlo di "basta che funzioni", per quanto mi riguarda il problema che vi esporrò è risolto.
D'altro canto, dal momento che questo simpatico, inspiegabile, comportamento ha comportato la perdita di circa 16 ore uomo (due giornate di lavoro, sì) mi sento di sottoporvelo per pareri e, non si sa mai, esperienza.
Dunque all'interno di una libreria sviluppata internamente e utilizzata nelle tre applicazioni proprietarie dell'azienda per cui lavoro abbiamo questo codice:
std::vector<Property*>::iterator it = m_kPropertyStorage.begin();
while(it != m_kPropertyStorage.end())
{
delete *it;
it++;
}
Non penso ci sia bisogno di tantissimi dettagli:
- Property: classe di dati contenente delle CString
- m_kPropertyStorage: vettore di puntatori a Property allocati nell'heap
Questo codice funzionava perfettamente in debug in tutte le applicazioni ed in release in due applicazioni. Nella terza applicazione, se compilata in release, originava puntualmente inspiegabili crash.
Dopo 16 ore di smarronamento e ripasso dell'onomastica, essendo io un brutale zappatore che ha sempre avuto in odio gli iteratori (il codice originale è di un mio collega) decido, per capire meglio cosa stia succedendo, di riscrivere il codice così:
Property* dummyPtr = NULL;
for(int i=0; i<m_kPropertyStorage.size();i++)
{
dummyPtr = m_kPropertyStorage[i];
if(dummyPtr)
delete dummyPtr;
dummyPtr = NULL;
}
Ovvero nascondendo l'iteratore nell'iterazione ed utilizzando gli operatori ed i metodi di stl::vector che permettono di utilizzarlo come un comune array.
Il codice... FUNZIONA!
Ora, la sfida per i guru è: cosa cambia tra le due implementazioni?
Per che motivo, solo in release e solo in una su tre applicazioni che usano la stessa libreria nello stesso modo (ah, scrivendo e leggendo il vettore in un singolo thread, nel caso ci fosse dubbio) la versione a "aritmetica degli iteratori" (teoricamente più "elegante") dava crash?
Misteri della programmazione.
D'altro canto, dal momento che questo simpatico, inspiegabile, comportamento ha comportato la perdita di circa 16 ore uomo (due giornate di lavoro, sì) mi sento di sottoporvelo per pareri e, non si sa mai, esperienza.
Dunque all'interno di una libreria sviluppata internamente e utilizzata nelle tre applicazioni proprietarie dell'azienda per cui lavoro abbiamo questo codice:
std::vector<Property*>::iterator it = m_kPropertyStorage.begin();
while(it != m_kPropertyStorage.end())
{
delete *it;
it++;
}
Non penso ci sia bisogno di tantissimi dettagli:
- Property: classe di dati contenente delle CString
- m_kPropertyStorage: vettore di puntatori a Property allocati nell'heap
Questo codice funzionava perfettamente in debug in tutte le applicazioni ed in release in due applicazioni. Nella terza applicazione, se compilata in release, originava puntualmente inspiegabili crash.
Dopo 16 ore di smarronamento e ripasso dell'onomastica, essendo io un brutale zappatore che ha sempre avuto in odio gli iteratori (il codice originale è di un mio collega) decido, per capire meglio cosa stia succedendo, di riscrivere il codice così:
Property* dummyPtr = NULL;
for(int i=0; i<m_kPropertyStorage.size();i++)
{
dummyPtr = m_kPropertyStorage[i];
if(dummyPtr)
delete dummyPtr;
dummyPtr = NULL;
}
Ovvero nascondendo l'iteratore nell'iterazione ed utilizzando gli operatori ed i metodi di stl::vector che permettono di utilizzarlo come un comune array.
Il codice... FUNZIONA!
Ora, la sfida per i guru è: cosa cambia tra le due implementazioni?
Per che motivo, solo in release e solo in una su tre applicazioni che usano la stessa libreria nello stesso modo (ah, scrivendo e leggendo il vettore in un singolo thread, nel caso ci fosse dubbio) la versione a "aritmetica degli iteratori" (teoricamente più "elegante") dava crash?
Misteri della programmazione.