Jeg har oprette en dynamisk tabel indeholdende indbygger-objekter:
Indbygger *tabel; tabel = new Indbygger[arraySize]; //Tabel med 50 indbyggere
Hver objekt består af to Strings "Navn og Cpr nr" samt pointere til ægtefæller, børn og forældre.
Når tabellen er fyldt op med indbyggere har jeg lavet en funktion der udvider tabellen og kopiere de gamle ojekter over:
Indbygger *udvid_tabel(Indbygger *arr, int &arraySize) { int newSize = arraySize*2; Indbygger *tempArr; tempArr = new Indbygger[newSize]; for(int i=0; i<arraySize; i++) tempArr[i] = arr[i]; delete [] arr; return tempArr; }
PROBLEMET: Pointerne bliver IKKE kopieret med over. Dvs. de peger stadig på den gamle adresse i tabellen som jo nu er sletttet. Hvordan får jeg pointerne i objekterne til at pege på den ny adresse???
Er du nu også sikker på, at du gerne vil lave det med pointere??? Når du vil sådan noget her, så er pointere muligvis ikke det smarteste... Men okay, det kan da lade sig gøre!
Indbygger *udvid_tabel(Indbygger *arr, int &arraySize) { int newSize = arraySize*2; Indbygger *tempArr; tempArr = new Indbygger[newSize]; for(int i=0; i<arraySize; i++) { tempArr[i] = arr[i]; if (arr[i].aegtefaelle!=NULL) tempArr[i].aegtefaelle=&tempArr[((int)arr[i].aegtefaelle-(int)arr))/sizeof(Indbygger)]; } delete [] arr; return tempArr; }
Jeg tror det skulle virke, men umiddelbart ikke det nemmeste kode at læse...
Vi skal finde indekset (i den nye tabel, tempArr) på den ægtefælle, som aegtefaelle-pointeren peger på. Når vi har fundet indekset, sætter vi aegtefaelle-pointeren i tempArray til at pege på adressen på elementet på dette indeks.
arr[i].aegtefaelle giver adressen på det element den peger på lige nu. Hvis vi trækker adressen på starten af arrayet fra, har vi antallet af bytes som pointeren peger ind i arrayet. Hvis vi dividerer med størrelsen af de enkelte objekter (sizeof(X) giver byte-størrelsen af X), har vi hvor mange elementer den peger forbi, altså indekset på aegtefaellen! Sådan.
binær træ, mener jeg.. kan man mestre et binært træ.. er man godt inde i pointere... vist også en meget hurtig måde at søge igennem..... nå det var bare en kommentar.
Ja, det er rigtigt der findes mange smartere strukturer til at holde sådan noget data i, hvis det skal være bare en smule fleksibelt. En kædet liste ville fx. være langt smartere, og meget nemmere at indsætte og slette i, men hvis det skal være et array, so be it!
Hvis du gerne vil have hjælp til at lave det som en kædet liste, så kan vi også finde ud af det...
Hvis ikke du har defineret en Assignment operator vil det gå galt! Du prøver at sætte indholdet af de to pointere lig med hinanden men da klassen ikke ved hvordan det gøres går det galt! Kompileren burde faktisk informere om at der ikke findes en operator!! Operatoren defineres på følgende måde i klassen
void operator = (CIndbygger& a) { Navn = a.Navn; CPRNr = a.CPRNr; Samlever = a.Samlever; //Alle de variable der skal kopieres kopieres her! }
Det burde løse dit problem! Så slipper du også for at bekymre dig om pointere og den slags!
Nej, det er ikke rigtigt. Den kan fint finde ud af at kopiere en pointer, når man sætter en struct lig med en anden. Det den gør helt konkret, er noget tilsvarende: memcpy(&DestStruct, &SourceStruct, sizeof(struct));
Når man bare kopierer dataindholdet fra en struct til en anden, vil pointere blive kopieret rigtigt. Det der derimod ikke vil blive kopieret er dynamisk oprettet hukommelse for en pointer inde i structen. Hvis vi har følgende:
struct A_struct { int a; char* b; };
void main() { A_struct a, b; a.b=new char[200]; b=a; } Nu vil selve arrayet fra a IKKE blive kopieret til b! Det er kun pointeren der bliver kopieret, så hvis man ændrer på arrayet i a, vil det også være ændret i b.
Problemet for zap er, at pointerene peger på objekter i et array, som han sletter lige efter. Pointerne skal selvfølgelig pege på objekter i det nye array.
Nej, det er det ikke. Han vil ikke kopiere indholdet af pointeren, han vil opdatere pointeren til at pege ind i det nye array, i stedet for at pege ind i det gamle, som han jo sletter. Hans problem vil bestemt ikke være løst ved det du gør, faktisk giver det NØJAGTIG samme resultat som han selv havde fundet frem til. Om man sætter pointeren explicit lig med pointeren fra den anden struct, eller om man memcopyer pointeren ved blot at sætte structen lig med den anden, giver nu engang stadig den samme pointer, som nu engang stadig er den forkerte.
Jeg ved godt det er en lidt anden løsning, men hvis kravet bare er et dynamisk array, hvorfor så ikke bruge STLs vector (svarer til et dynamisk array)? Det ville se nogenlunde såddan ud: vector<Indbygger*> tabel;
Sæt en ny indbygger ind: Indbygger *pJohnDoe=new Indbygger; tabel.push_back(pJohnDoe);
Indexering foregår som normalt (kant operatoren er defineret): Indbygger *pCur=tabel[42]; tilsvarende (dog med sanity check): Indbygger *pCur=tabel.at(42);
Det eneste man skal huske er så, at huske at delete entries, før (eller samtidigt med :) man fjerner dem fra listen. Ellers kan man jo selvfølgelig også bare erklære listen som: vector<Indbygger> tabel; ..Men så er vi tilbage ved samme ballade med assignment/kopiering af strukturen/klassen.
.. Men mens vi er ved STL kunne du også bare bruge string klassen til at opbevare navnene med. Den sørger selv for at kopiere ved assignment. string sTemp="Hello world."; string sTemp2=sTemp;
Hvis sTemp bliver destructed før sTemp2 (hvilket ikke vil være tilfældet i dette eksempel ;), vil sTemp2 automatisk overtage ejerskabet af hukommelsen (hvor strengen rent faktisk ligger).
Et array af pointere (ikke pointere pointere) vil være langt smartere, for så behøver en indbygger aldrig at skifte adresse i hukommelsen, og så behøver man ikke opdatere nogle pointere.
Desuden vil det være mere effektivt (eg. hurtigere), da man ikke skal slette, oprette og kopiere en masse hukommelse.
OK! Jeg er nok ikke nok inde i problemstillingen til at give et helt konkret svar! Men det var da enormt hyggeligt og lærerigt! *GGG*
Synes godt om
Slettet bruger
09. juni 2000 - 16:02#15
Så er opgaven afleveret og jeg svaret fra DMK virkede fint. I har ret i at et array af pointere vil være smartere, så ved jeg det til næste gang: ) Tak for hjælpen!
ZAP
Synes godt om
Ny brugerNybegynder
Din løsning...
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.