[c++] Pointer vraag, verschil &*iets* of new *iets*

Pagina: 1
Acties:

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
Heren,

Voordat jullie me doorverwijzen naar de tig pagina's die uitleggen wat pointers zijn, waarom ze bestaan, hoe ze ontstaan zijn en wat hun rol in de recentelijke crisis in Oeganda was, zou ik graag even vermelden dat ik een redelijk duidelijk beeld heb van pointers.

Ik heb dan ook veel gezocht, maar ik ben er nog niet achter wat/of concreet het verschil is tussen de volgende codes.

voorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

using namespace std;

void gnoe(int* a) {
    *a = 12;
}

void main(void) {
    int a;
    gnoe(&a);
    cout << a << endl;
}

tegenover:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

using namespace std;

void gnoe(int* a) {
    *a = 12;
}

void main(void) {
    int* a = new int;
    gnoe(a);
    cout << *a << endl;
}

los van dat het zichtbare resultaat hetzelfde is, lijken de codes ook gewoon hetzelfde te doen, maar ik weet het niet zeker :)

Zitten er voordelen aan om de een of andere methode te gebruiken? of doen ze inderdaad exact hetzelfde?

alvast bedankt!

oprecht vertrouwen wordt nooit geschaad


  • John_Glenn
  • Registratie: Augustus 2001
  • Laatst online: 28-08-2023

John_Glenn

verdeelt de whooping.

Als je ergens in een functie "int a;" gebruikt, en je verlaat die functie, dan wordt a geloosd, en de bijhorende geheugenruimte vrijgegeven. Als je daarentegen de tweede optie volgt, dan is a geen int maar een pointer-to-int. Dus als je de functie verlaat, wordt nog steeds a geloosd, maar niet de geheugenruimte vrijgemaakt. Tweede methode is dus nogal gevoelig voor geheugenlekken...

  • Klippy
  • Registratie: Oktober 2000
  • Laatst online: 22-02 17:52

Klippy

Still Game

edit:

Laat maar ,ik weet het al, sliep half :)

[ Voor 92% gewijzigd door Klippy op 23-04-2006 15:59 ]

Steam | SXQncyBhbGwgZ29vZCwgbWFuISDwn5iO


  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
Als er inderdaad verschil in zit, dan maak je het jezelf dus onnodig moeilijk met de tweede methode, aangezien je dan zelf achter je bitjes aan moet. Niet gebruiken dus?

oprecht vertrouwen wordt nooit geschaad


Verwijderd

in methode 1 wordt variabele "a" aangemaakt van type int, waarvan je het adres opvraagt. in methode 2 wordt vaiabele "a" aangemaakt van het type int*, pointer to int dus, je maakt een nieuwe int aan waar geen naam aan zit waar je met "a" naar verwijst, dat stukje geheugen is dus *a geworden.
code:
1
2
1: &a --> a (int)
2: a (int*) --> [*a] ("new" int)

Ik wil je er er wel op wijzen dat in C eerder de malloc constructie gebruikt wordt, dus
code:
1
2
int *a;
a=malloc(sizeof(int));
i.p.v.
code:
1
int *a=new int;

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:22
In beide gevallen maak je een int 'object'. De verschillen zitten 'm er in hoe je er een referentie naar krijgt (in het eerste geval wordt 'ie direct gebonden aan een variabele met naar 'a', in het tweede geval krijg je er een pointer naar die aan 'a' wordt gebonden).

Het verschil waar jij op doelt zit 'm echter in de levensduur van de objecten. In het eerste geval wordt het object geïnitialiseerd op de plek waar 'ie in de code staat en weer opgeruimd zodra de bijbehorende variabele out-of-scope gaat (dus bij de eerstvolgende '}' in dit geval). In het tweede geval bepaal jij expliciet wanneer 'ie (gealloceerd en) geïnitialiseerd wordt (met een aanroep naar new) en moet je ook aangeven wanneer 'ie opgeruimd (en gedealloceerd) moet worden!
Atgast schreef op zondag 23 april 2006 @ 15:55:
Als er inderdaad verschil in zit, dan maak je het jezelf dus onnodig moeilijk met de tweede methode, aangezien je dan zelf achter je bitjes aan moet. Niet gebruiken dus?
Niet als je 'm alleen binnen de scope van je functie (of wherever) nodig hebt. Dan maak je het jezelf inderdaad onnodig moeilijk.

@RoadRunner84: een int is in C++ een object, alleen met een fundamental type en geen class type en derhalve ook geen members.

[ Voor 36% gewijzigd door Soultaker op 23-04-2006 16:09 ]


Verwijderd

Soultaker schreef op zondag 23 april 2006 @ 15:56:
In beide gevallen maak je een int 'object'.
[...]
Dat ook, maar C++ kent geen int object, wordt gewoon weer een int. Let er wel op dat je met new ook moet destroy-en, en met malloc ook moet free-en.

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
Soultaker schreef op zondag 23 april 2006 @ 15:56:

[...]

Niet als je 'm alleen binnen de scope van je functie (of wherever) nodig hebt. Dan maak je het jezelf inderdaad onnodig moeilijk.
Maar de pointer a ben je toch ook kwijt zodra je buiten de main komt?
Dus dan heb je de waarde misschien nog wel, maar weet je niet meer waar je 'm moet vinden, toch?
John_Glenn schreef op zondag 23 april 2006 @ 15:49:
Als je ergens in een functie "int a;" gebruikt, en je verlaat die functie, dan wordt a geloosd, en de bijhorende geheugenruimte vrijgegeven. Als je daarentegen de tweede optie volgt, dan is a geen int maar een pointer-to-int. Dus als je de functie verlaat, wordt nog steeds a geloosd, maar niet de geheugenruimte vrijgemaakt. Tweede methode is dus nogal gevoelig voor geheugenlekken...
Ik heb het net even getest onder XP, met de volgende code:
C++:
1
2
3
4
5
6
7
8
9
10
11
#include <vector>

using namespace std;

int main() {
    vector<int*> a;
    for(int i=0; i<13107200; i++) {
        a.push_back(new int);
    }
    return 0;
}

Echter kreeg windows meteen z'n geheugen terug toen het programma afliep.

oprecht vertrouwen wordt nooit geschaad


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:33
Echter kreeg windows meteen z'n geheugen terug toen het programma afliep.
Ja gelukkig maar...
Een memory leak wil niet zeggen dat, na afloop van het programma het geheugen niet aan windows teruggegeven wordt.

https://fgheysels.github.io/


Verwijderd

whoami schreef op zondag 23 april 2006 @ 16:11:
[...]

Ja gelukkig maar...
Een memory leak wil niet zeggen dat, na afloop van het programma het geheugen niet aan windows teruggegeven wordt.
Als het over geheugen van het programma zelf gaat wel, bij geheugen dat van meerdere programma's is niet. Daar heb je immers je virtual mode voor :)

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:22
Atgast schreef op zondag 23 april 2006 @ 16:07:
Maar de pointer a ben je toch ook kwijt zodra je buiten de main komt?
Dus dan heb je de waarde misschien nog wel, maar weet je niet meer waar je 'm moet vinden, toch?
In jouw voorbeeld heb je er geen referenties meer naar als a uit scope verdwenen is, maar dan blijft 'ie dus wel gealloceerd in de heap. Dan is 'ie dus ook nooit opgeruimd (maakt voor een int niet uit, maar bijvoorbeeld een netwerk socket blijft dan misschien ook open staan als je 'm initialiseert en er later niet meer naar omkijkt).
Ik heb het net even getest onder XP, met de volgende code:
C++:
1
2
3
4
5
6
7
8
9
10
11
#include <vector>

using namespace std;

int main() {
    vector<int*> a;
    for(int i=0; i<13107200; i++) {
        a.push_back(new int);
    }
    return 0;
}

Echter kreeg windows meteen z'n geheugen terug toen het programma afliep.
Inderdaad. Moderne besturingssystemen zorgen ervoor dat alle resources die toegekend worden aan een proces (behalve misschien shared memory e.d. die tussen processen gedeeld worden) vrijgegeven worden als het proces afgelopen is. Dat geldt dus ook voor open bestanden die je niet gesloten hebt en de meeste locks op synchronisatieobjecten. Dat is een feature van het besturingssysteem - de C++ standaard zegt er verder niets over.

Denk er wel aan dat als het besturingssysteem je geheugen opruimt, objecten niet goed opgeruimd worden! Er zit dus wel degelijk verschil tussen objecten vrijgeven met delete, zoals het hoort, of ze door het besturingssysteem op laten ruimen, maar dat merk je pas bij types met een destructor die ook meer doet dan alleen geheugen vrijgeven.

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
ah, altijd gedacht dat memory leak sloeg op het langzaam dichtslibben van het OS door crappy programma's :) (hetgeen natuurlijk wel opgaat indien het programma's zijn die op de achtergrond draaien)
Soultaker schreef op zondag 23 april 2006 @ 16:15:
[...]

Denk er wel aan dat als het besturingssysteem je geheugen opruimt, objecten niet goed opgeruimd worden! Er zit dus wel degelijk verschil tussen objecten vrijgeven met delete, zoals het hoort, of ze door het besturingssysteem op laten ruimen, maar dat merk je pas bij types met een destructor die ook meer doet dan alleen geheugen vrijgeven.
hoe bedoel je precies, iets anders dan geheugen vrijgeven?
(bv. saven ed. hoort toch niet in de destructor?)

[ Voor 60% gewijzigd door Arjan op 23-04-2006 16:18 ]

oprecht vertrouwen wordt nooit geschaad


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:22
Hangt er vanaf wat je klasse precies doet. Het punt is dat in het algemeen een klasse verwacht dat 'ie wordt geïnstantieerd met z'n constructor en wordt opgeruimd met z'n destructor en het is dus verstandig om je aan te wennen daar aan te voldoen.

@MSalters: je bent laat. ;)

[ Voor 10% gewijzigd door Soultaker op 23-04-2006 17:02 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12-2025
Verwijderd schreef op zondag 23 april 2006 @ 16:00:
Dat ook, maar C++ kent geen int object, wordt gewoon weer een int.
Eh? C++ kent wel degelijk int objecten. Sterker nog, elke instantie van het type int is een int object.
De objecten in een programma zijn simpel gezegd alle variabelen en alle constanten. Een gewone int is een variabele, een const int een constante, dus beide zijn daarom objecten.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 23:40
Atgast schreef op zondag 23 april 2006 @ 16:15:
ah, altijd gedacht dat memory leak sloeg op het langzaam dichtslibben van het OS door crappy programma's :)
Is ook goed mogelijk als mijn programma niet afgesloten wordt, of heel snel resources/handles/processortijd/schijfruimte/whatever reserveert en niet terug geeft.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op zondag 23 april 2006 @ 16:14:

Als het over geheugen van het programma zelf gaat wel, bij geheugen dat van meerdere programma's is niet. Daar heb je immers je virtual mode voor :)
Klok, klepel? :)
Virtual (x86) mode is heel wat anders, namelijk een manier om legacy 16-bit real-mode te blijven ondersteunen in 32 bit protected mode omgevingen (dit zorgt er dus voor dat je bijvoorbeeld oude DOS applicaties kunt runnen). Wat jij bedoelt is virtual memory, maar hoe dat geheugen-lek probleem en het verschil tussen één of meerdere applicaties daarin past snap ik niet helemaal.

Bottom line is dat vrijwel alle resources die je applicatie heeft getracked worden door windows, en ze worden vrijgegeven op het moment dat je applicatie sterft. Shared resources hebben over het algemeen een reference count, die ook worden vrijgegeven op het moment dat de laatste applicatie die nog referenties heeft naar een dergelijke resource stopt.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12-2025
Atgast schreef op zondag 23 april 2006 @ 16:15:
hoe bedoel je precies, iets anders dan geheugen vrijgeven?
Wat denk je dat
C++:
1
TempFile::~TempFile()
doet?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1