20. marts 2004 - 10:06Der er
10 kommentarer og 1 løsning
Uduelig kode
Hvad i følgende kode kan sætte AntalBrugte til en ulovlig værdi?
template <class T> class DynArray {
private: T *Graf; int AntalBrugte; //Antallet af brugte pladser, og index på næste ledige plads int MaxAntal; //det antal der kan fyldes op til, uden der skal vokses int Iterator; //iterator brugt ved first next more void Grow() { T * temp = new T[MaxAntal+=1]; printf("Jeg vokser!\n"); for (int i = 0; i<AntalBrugte ; i++) temp[i] = Graf[i]; delete [] Graf; Graf = temp; }
public: DynArray() { AntalBrugte = 0; MaxAntal = 10; Iterator = 0; Graf = new T[MaxAntal]; } int Tilfoj(T *N) { if (AntalBrugte>=MaxAntal) Grow(); Graf[AntalBrugte] = (*N); AntalBrugte++; return AntalBrugte -1; //index på sidst indsatte } void FjernSidste() { if ( AntalBrugte>0) { AntalBrugte--; } else throw Exception("DynArray::FjernSidste - forsøg på at fjerne fra tom liste!");
} T * operator[](int Index) { if (Index < AntalBrugte) return &Graf[Index]; else throw Exception("Der blev spurgt på et ulovligt element DynArray::operator[] Index: "+IntToStr(Index)); } int GetIterator() { return Iterator; } int GetAntalBrugte() { int temp = AntalBrugte; return temp; } void SatIterator(int Plads) { if ((AntalBrugte <= Plads) || (AntalBrugte <0)) throw Exception("DynArray::SatIterator, forsøg på ulovlig indstilling af iterator!"); else Iterator = Plads;
} void Nulstil() { delete Graf; Graf = new T[MaxAntal]; AntalBrugte = 0; Iterator = 0; } void First() { Iterator = 0; } void Last() { Iterator = AntalBrugte -1; } void Next() { if (Iterator <= AntalBrugte) Iterator++; else throw Exception("DynArray::Next() - forsøg på at iterere ud over listen - Iterator:"+IntToStr(Iterator)); } void Previous() { if (Iterator-1 >= 0) Iterator--; else throw Exception("DynArray::Previous - forsøg på læsning af index mindre end 0"); } bool More() { return (Iterator < AntalBrugte); } bool Less() { return (Iterator-1 >= 0); } T * GetLast() { if (AntalBrugte>0) return &Graf[AntalBrugte-1]; else throw Exception("DynArray::GetLast forsøg på at læse fra tom liste!!!");
} T * GetThis() { return &Graf[Iterator]; } int GetIteratorValue() { return Iterator; } };
koden afvikles i bcb6 hvis det har nogen betydning.
Når jeg har puttet nogle forskellige data ind i listen og bruger nogle af metoderne, så er AntalBrugte ligepludselig sat til 19568556 i en liste med 2 elementer, det giver selvfølgelig fejl når jeg itererer derud af. Og da det er en privat variabel må det være et eller andet sted i ovenstående kode den er gal...
Default = operator laver jo memcpy og når en af kopierne laver en delete af en dynamisk allokeret member variabel så peger den andens kopi jo på noget som systemet tror er ledigt og kan genbruges.
Hvo, du siger noget der, jeg har da vist en enkelt klasse der bruger pointere hvor jeg ikke har forsynet den med en = operator... Det kigger jeg lige på.
_jepsen : du kan prøve at tilføje et data break point i din klasse, run->add breakpoint.
Du mangler copy constructor og assigment operator for din class, lav den privat med en throw i sig hvis du ikke mener der er nogen der bør bruge dem.
Build all og se efter om der er nogen temporary used for xxx, så få dem løst.
Nu er jeg ikke sikker men kan dette ikke gå galt for 0 elementer? void Last() { Iterator = AntalBrugte -1; }
// her går det galt med negativt Index T * operator[](int Index) { // måske unsigned??? if (Index < AntalBrugte) return &Graf[Index]; else throw Exception("Der blev spurgt på et ulovligt element DynArray::operator[] Index: "+IntToStr(Index)); }
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.