Leif.ross Skrevet 4. desember 2012 Del Skrevet 4. desember 2012 (endret) Aldri vært spesielt stødig på pointers, så jeg spør etter litt visdom her! running = true; int nr = 0; PrimitiveObj * prop; while(running){ nr = getNumberOfPrimitives()-1; for(int r = 0; r < nr; r++) { prop = getPrimitive(r); glm::vec3 pos = prop->getPos()+glm::vec3(0,1.0f,0); prop->setPos(pos); } boost::this_thread::yield(); } delete prop; boost::this_thread::yield(); running = false; Denne kodesnutten blir styrt av en annen tråd, så loopen er ikke evig btw! Feilkode: HEAP[TTTTT.exe]: HEAP: Free Heap block 20385a8 modified at 20385e0 after it was freed Feilen blir trigget når "nr" er større enn ett element, bruker en pointer for å få referansen til PrimitiveObj'en som det er snakk om, istedenfor å bare få verdien. Får den fra disse funksjonene: int getNumberOfPrimitives(){ return prims.size(); } PrimitiveObj * getPrimitive(int input) { return prims[input]; } Hva gjør jeg galt? Endret 5. desember 2012 av Leif.ross Lenke til kommentar
BlueEAGLE Skrevet 4. desember 2012 Del Skrevet 4. desember 2012 free(prop); prop = NULL; Først så kaller du free på en variabel og så forsøker du å tilordne variabelen en verdi... Feilmeldingen sier at du forsøker å endre (les: tilordne en verdi til) variabelen etter at den har blitt frigitt. Hva kan være galt? Lenke til kommentar
LonelyMan Skrevet 4. desember 2012 Del Skrevet 4. desember 2012 (endret) Kommenter alltid ut linje for linje og verifiser at retur-resultatene stemmer med det du vil frem til. Endret 4. desember 2012 av LonelyMan 1 Lenke til kommentar
Leif.ross Skrevet 4. desember 2012 Forfatter Del Skrevet 4. desember 2012 free(prop); prop = NULL; Først så kaller du free på en variabel og så forsøker du å tilordne variabelen en verdi... Feilmeldingen sier at du forsøker å endre (les: tilordne en verdi til) variabelen etter at den har blitt frigitt. Hva kan være galt? Får feilkoden i "for-loopen", altså før den kommer til dette stadiet. Lenke til kommentar
Leif.ross Skrevet 4. desember 2012 Forfatter Del Skrevet 4. desember 2012 (endret) Kommenter alltid ut linje for linje og verifiser at retur-resultatene stemmer med det du vil frem til. Lurer på om det faktisk kan være et multithreading problem istedenfor et pointer problem, får nå bare problemer med den når jeg spammer nye objekter. Kan være at de forskjellige trådene prøver å skrive til samme variabel elns. Hmm. Edit: Yes, problemet er at to tråder prøver å skrive til samme variabel samtidig, må finne en vei ut av det! Skal prøve å finne ut hvordan mutex locks fungerer, men det er jo umulig å finne noe oppdatert info om det, bruker boost tråder btw! Endret 4. desember 2012 av Leif.ross Lenke til kommentar
tomsi42 Skrevet 4. desember 2012 Del Skrevet 4. desember 2012 Er dette C eller C++ ? (Ser vel ut som C++ etter en nærmere studie). Ser du har både free og delete i kodeeksempelet. De skal ikke blandes. Objekter laget med new skal slettes med delete, og free brukes på resultat fra alloc familen av funskjoner. Men hvem er det som har ansvaret for å slette objektet som returneres fra getPrimitive()? din kode eller biblioteket der getPrimitive() kommer fra? Lenke til kommentar
Leif.ross Skrevet 4. desember 2012 Forfatter Del Skrevet 4. desember 2012 (endret) getPrimitive er en funksjon i et object jeg har laget selv, og det slettes i en helt annen del av koden. Det er C++. Endret 4. desember 2012 av Leif.ross Lenke til kommentar
LonelyMan Skrevet 4. desember 2012 Del Skrevet 4. desember 2012 Er det OpenGL du koder? Lenke til kommentar
Leif.ross Skrevet 4. desember 2012 Forfatter Del Skrevet 4. desember 2012 (endret) Yes sir! OpenGL3.3! void generatePrimitive(){ PrimitiveObj * obj = new PrimitiveObj(); obj->generate(); obj->setPos(getPlayerPos()+getEye()*4.0f); prims.push_back(obj); } Usikker på om det er denne snutten som feller meg nå, har en følelse av at jeg bare kopierer den samme pointeren hver gang denne funksjonen blir kjørt. Feilkoden er nå: First-chance exception at 0x0133ed89 in TTTTT.exe: 0xC0000005: Access violation reading location 0xfeeefefe. Unhandled exception at 0x772215de in TTTTT.exe: 0xC0000005: Access violation reading location 0xfeeefefe. Endret 4. desember 2012 av Leif.ross Lenke til kommentar
GeirGrusom Skrevet 5. desember 2012 Del Skrevet 5. desember 2012 Hvorfor gjør du free på det i det hele tatt? Etter koden å dømme, så er dette en peker som denne funksjonen ikke burde ha noen som helst kontroll over. 1 Lenke til kommentar
Leif.ross Skrevet 5. desember 2012 Forfatter Del Skrevet 5. desember 2012 Hvorfor gjør du free på det i det hele tatt? Etter koden å dømme, så er dette en peker som denne funksjonen ikke burde ha noen som helst kontroll over. Koden er modifisert nå, og bruker ikke free! Problemet ser ut til å ligge i den siste funksjonen jeg postet. Lenke til kommentar
zotbar1234 Skrevet 5. desember 2012 Del Skrevet 5. desember 2012 free(prop); prop = NULL; Først så kaller du free på en variabel og så forsøker du å tilordne variabelen en verdi... Feilmeldingen sier at du forsøker å endre (les: tilordne en verdi til) variabelen etter at den har blitt frigitt. Isolert sett er det ingenting galt med disse to linjene. Man kan gjerne sette en peker til noe (være det et nytt objekt eller NULL) etter å ha frigjort det objektet som pekeren pekte på opprinnelig. Lenke til kommentar
zotbar1234 Skrevet 5. desember 2012 Del Skrevet 5. desember 2012 Aller først -- kan du poste det minste komplette eksempelet som illustrerer problemet? Aldri vært spesielt stødig på pointers, så jeg spør etter litt visdom her! running = true; int nr = 0; PrimitiveObj * prop = NULL; while(running) { nr = getNumberOfPrimitives(); for(int r = 0; r < nr; r++) { prop = getPrimitive(r); glm::vec3 pos = prop->getPos()+glm::vec3(0,1.0f,0); prop->setPos(pos); } } if(prop!=NULL) { free(prop); prop = NULL; } running = false; //delete prop; Denne kodesnutten blir styrt av en annen tråd, så loopen er ikke evig btw! Aha, begynte å lure på akkurat det. Flere har påpekt på free()-vs-delete, og du skal definitivt ikke blande de to sammen. Du nevner også threading -- kan feilen skyldes at objektene blir manipulert fra flere tråder og derfor har man en tråd som aksesserer et objekt som er blitt slettet i en annen tråd? (...) bruker en pointer for å få referansen til PrimitiveObj'en som det er snakk om, istedenfor å bare få verdien. Jeg sliter med å forstå hvordan dette utsagnet gir mening. Får den fra disse funksjonene: int getNumberOfPrimitives(){ return prims.size(); } PrimitiveObj * getPrimitive(int input) { return &prims[input]; } Er prims global? Hvis ja, hvordan blir tilgangen til den synkronisert fra flere tråder? Du bruker push_back(), men husk på at hvert kall på push_back() kan potensielt forårsake en reallokering i den underliggende vektoren, som vil gjøre samtlige av de adressene du har fått gjennom getPrimitive() ugyldige. Lenke til kommentar
tomsi42 Skrevet 5. desember 2012 Del Skrevet 5. desember 2012 Isolert sett er det ingenting galt med disse to linjene. Man kan gjerne sette en peker til noe (være det et nytt objekt eller NULL) etter å ha frigjort det objektet som pekeren pekte på opprinnelig. Faktisk så kan det være en god ide å sette pekeren til NULL, både fordi free ikke gjør det, og fordi det kan være lettere å fange opp feil da. Lenke til kommentar
Leif.ross Skrevet 5. desember 2012 Forfatter Del Skrevet 5. desember 2012 Aller først -- kan du poste det minste komplette eksempelet som illustrerer problemet? Aha, begynte å lure på akkurat det. Flere har påpekt på free()-vs-delete, og du skal definitivt ikke blande de to sammen. Du nevner også threading -- kan feilen skyldes at objektene blir manipulert fra flere tråder og derfor har man en tråd som aksesserer et objekt som er blitt slettet i en annen tråd? Jeg sliter med å forstå hvordan dette utsagnet gir mening. Er prims global? Hvis ja, hvordan blir tilgangen til den synkronisert fra flere tråder? Du bruker push_back(), men husk på at hvert kall på push_back() kan potensielt forårsake en reallokering i den underliggende vektoren, som vil gjøre samtlige av de adressene du har fått gjennom getPrimitive() ugyldige. Ideen var å lagre alle pointerene i en vektor, slik at jeg senere kan bruke denne vektoren for å få tilgang til alle pointerene, som igjen gir tilgang til objektene. Jeg har en rendering tråd som bare skal lese fra objektene, og rendre på bakgrunn av den informasjonen, og en fysikk tråd, som bare leser og oppdaterer informasjonen for hvert objekt. Trådene er ikke helt synkroniserte, men jeg bruker mutex locks for å hindre at to tråder prøver å kommme innpå samme variabel samtidig. Lenke til kommentar
zotbar1234 Skrevet 5. desember 2012 Del Skrevet 5. desember 2012 Trådene er ikke helt synkroniserte, men jeg bruker mutex locks for å hindre at to tråder prøver å kommme innpå samme variabel samtidig. Som sagt, husk at 1 push_back() betyr at alle iteratorer (og pekere) til vectorens innhold ikke er gyldige lenger. Lenke til kommentar
Leif.ross Skrevet 5. desember 2012 Forfatter Del Skrevet 5. desember 2012 Som sagt, husk at 1 push_back() betyr at alle iteratorer (og pekere) til vectorens innhold ikke er gyldige lenger. Gjelder dette selv om jeg legger til pekerne i vektoren, og ikke selve objektet? Lenke til kommentar
zotbar1234 Skrevet 5. desember 2012 Del Skrevet 5. desember 2012 Gjelder dette selv om jeg legger til pekerne i vektoren, og ikke selve objektet? Din getPrimitive() returnerer adressen til et element i vectoren. Dette betyr at når du tar en push_back() (dvs. kaller generatePrimitive()), vil ikke nødvendigvis adressen være gyldig lenger. Du kan legge til shared_ptr/vanlig peker heller enn objektene selv i vectoren, men hvorvidt det gir mening er det vanskelig å si uten å kjenne til programmet. Lenke til kommentar
Leif.ross Skrevet 5. desember 2012 Forfatter Del Skrevet 5. desember 2012 Oppdatert med ny kode i OP! Fortsatt feil? Lenke til kommentar
zotbar1234 Skrevet 5. desember 2012 Del Skrevet 5. desember 2012 (endret) Oppdatert med ny kode i OP! Fortsatt feil? Bedre, men (som nevnt alt), bør du redusere dette til det minste komplette eksempelet. Får du den samme feilen fremdeles? (dette er litt på siden av det opprinnelige problemet, men (siden du først bruker boost), hvorfor gidder du å syssle med manuell deallokering? boost::shared_ptr gjør at du slipper å tenke på delete. Det å faktisk unngå å kalle delete eksplisitt er et nokså prisverdig mål i seg selv i C++). Endret 5. desember 2012 av zotbar1234 Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå