Avatar billede mxs Nybegynder
31. oktober 2005 - 18:12 Der er 19 kommentarer og
1 løsning

En vild pointer. Hvad gør den egentlig?

Hej eksperten.dk

Jeg har laenge gaaet og undret mig over hvad en vild pointer egentlig gør?

int* func()
{

  int x = 5;
  return &x;

}

Hvad kan der, i vaerste tilfaelde, ske?

Paa forhaand tak,
Martin Slot
Avatar billede arne_v Ekspert
31. oktober 2005 - 18:20 #1
den kode returnerer en pointer som peger på memory der ikke
er allokeret efter retur

hvis du bruger den så kan og vil andre funktioner have ændret den så den
ikke er 5

a[*wildptr] vil så ikke være a[5] men a[-111111111111] og dit program vil crashe

eller det mempory bliver allokeret til noget andet og du sætter det
*wildptr = 6 og du får noget andet korrekt kode til at crashe
Avatar billede Slettet bruger
31. oktober 2005 - 18:21 #2
At du returnerer en pointer til noget der er allokeret på stack-frame og som ikke er en gyldig position når functionen returnere så den er ikke rigtig god den funktion ;)
Avatar billede arne_v Ekspert
31. oktober 2005 - 18:21 #3
ved gentagen brug så er der stor sandsynlighed for at programmet vil crashe

men det allerværste er det sidste når de crasher i noget helt andet kode
end det som er skyld i fejlen
Avatar billede mxs Nybegynder
31. oktober 2005 - 18:25 #4
Har nemlig hørt mange skrækhistorier om hvad der kan ske, saa som at din skaerm fucker op.
Avatar billede mxs Nybegynder
31. oktober 2005 - 18:26 #5
Men den peger vel bare paa en tilfaeldig adresse paa stacken som kan indholde hvad som helst?
Avatar billede arne_v Ekspert
31. oktober 2005 - 18:28 #6
ja men brug af den kan få alle mulige konsekvenser
Avatar billede mxs Nybegynder
31. oktober 2005 - 18:31 #7
Den kan vel naermest gaa ind og aendre paa noget som et andet program har i brug?
Avatar billede Slettet bruger
31. oktober 2005 - 18:32 #8
Det kommer jo meget an på hvad man vælger at bruge den pointer til. Hvis man blot aflæser et en int value fra den sker der jo ikke andet end at værdien vil være forkert når programmet har kørt. Ja det i sig selv kan jo være slemt nopk hvis man skal bruge det program til noget. Være kan de gå hvis du begynder at skrive til, men hvad der sker er mere eller mindre tilfældigt.

Pointen er bare lad være med at gør sådan.
Avatar billede arne_v Ekspert
31. oktober 2005 - 18:33 #9
ikke et andet program

men en anden del af samme program
Avatar billede arne_v Ekspert
31. oktober 2005 - 18:34 #10
en lille analogi: det kan gå godt at køre 10 km på motorvej med lukkede øjne, men
det er ikke at anbefale !  :-)
Avatar billede mxs Nybegynder
31. oktober 2005 - 18:47 #11
Du har fat i noget.
Jeg siger tak.
Avatar billede mxs Nybegynder
31. oktober 2005 - 18:50 #12
Er det kun i Linux hvor programmerne har deres eget space paa stacken? Er det ikke i windows, hvor du har adgang til et faelles space saa man paa den maade kan fucke op i et andet kørende program?
Avatar billede arne_v Ekspert
31. oktober 2005 - 18:52 #13
Alle nyere styre systemer har seperat addresserum for forskellige processer/programmer.

Både Linux og nyere Windows.

Men i de gode gamle DOS dage kunne man slå styre systemet ihjeld ved at overskrive
dele af memory.
Avatar billede mxs Nybegynder
31. oktober 2005 - 18:58 #14
Okay. Cool. Smidt et svar og jeg skal dele point ud.
Avatar billede arne_v Ekspert
31. oktober 2005 - 19:00 #15
.
Avatar billede bertelbrander Novice
31. oktober 2005 - 20:38 #16
Jeg lavede et lille testprogram:

#include <iostream>

int *func1()
{
  int x;
  x = 123;
  std::cout << x << std::endl;
  return &x;
}

void func2()
{
  int x;
  std::cout << x << std::endl;
}

int main()
{
  int *p =func1();
  *p = 321;
  func2();
}

Hvis jeg kompilerer med g++ på windows, skriver det 123 og 321, nogen vil nok hævde at det betyder at programmet "virker".

I gode gamle dos tider kunne man skrive til skærmen med en "vildfaren" pointer, det kunne være ret praktisk.
Avatar billede mollevp Nybegynder
02. november 2005 - 00:55 #17
Bertel jeg må lige høre, har jeg fat i noget af det rigtige hvis jeg siger at grunden til at det der virker er, at compileren ligger et bestemt adresse område ud til automatiske variabler og det der sker er så:

- int allokeres på adresse X
- int går ud af scope, vi har dog stadig adressen i p
- vi kan godt skrive til adressen - da det er valid adresse område for vores program
- ny int allokeres på adressen X, da der ikke bør ligge noget
- vi kan så udskrive variable på adressen X

Er dette ikke compiler specifikt, jeg mener ville det ikke kunne gå galt med andre compilere en g++?
Avatar billede bertelbrander Novice
02. november 2005 - 01:10 #18
Du har ret i din analyse.

Jo, det er meget compiler specifikt om det "virker". g++ og Digital Mars compilerne giver 123 og 321, BorlandC++ og Visual C++ giver et andre resultater.

Hvis vi holder os til standarden vil den sige at det er "undefind behavior", og så kan alt ske.

Ordentlige compilere giver en warning hvis man forsøger at returnere en pointer til en lokal variabel (som i func1) og hvis man forsøger at bruge en variabel der ikke er initialiseret (som i func2).
Avatar billede mollevp Nybegynder
02. november 2005 - 01:12 #19
Ok, takker - jeg ville lige være sigger på at jeg havde forstået det..
mvh Morten
Avatar billede bertelbrander Novice
02. november 2005 - 20:39 #20
Et andet eksempel på et program med vild pointer der "virker":
#include <iostream>
int main()
{
  int *p = new int [100];
  delete [] p;
  p[40] = 12345678;
  p = new int [100];
  std::cout << p[40] << std::endl;
  delete [] p;
}

Det "virker" med alle de 4 compilere på windows som jeg har.
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester