Toon posts:

[C++] call by value

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb 2 string pointers waarvan ik 1 als werkruimte (tmp) gebruik en 1 als sjabloon (sjabloon). Het is dus de bedoeling dal alleen de werkruimte veranderd en het sjabloon niet.

{
char *tmp;
char *sjabloon= "start /Dc:\\mrtg-2.9.17\\bin perl mrtg --logging=eventlog ";
int i=0;

while (i<aantCFG)
{
strcpy(tmp,sjabloon);
strcat(tmp,alleCFGs[i][0]);
system(tmp);
i++;
}
}

Ik heb op deze code al een aantal variaties geprobeerd, maar ja, ik ben niet zo'n held met pointers dus ik zal wel in de goede richting zitten maar niet helemaal. Ik heb ook al andere pointer gerelateerde onderwerpen gelezen maar niets gevonden wat mij kon helpen.

Wie ziet waar ik de fout in ga?

  • whoami
  • Registratie: December 2000
  • Laatst online: 07-09 19:30
Wat is uw fout precies? Je vraagt hier waar je in de fout gaat, maar we weten niet wat je fout is.

Is het uw bedoeling dat enkel tmp wijzigt en sjabloon ongewijzigd blijft?
Zit die while in een functie die aangeroepen wordt? Zoja post dan eens de header van die functie, hoe je ze oproept enz...

Kortom: meer info.

[Edit]Als ik die code zo bekijk staat er nergens een regel code die ervoor zorgt dat sjabloon wijzigt. (Behalve de assignment dan). Dus, nu ben ik nog meer :?

https://fgheysels.github.io/


Verwijderd

Wil je tmp eens declareren als

char tmp[100];

want je bent naar niet geaddreseerd geheugen aan het schrijven.

Verwijderd

Je gebruikt char *tmp. Deze pointer wordt NIET geinitialiseerd en wijst dus naar nergens.
Voor elke strcpy een malloc doen ter grote van (lengte) van je sjabloon + de lengte van wat je er nog achter plakt + 1 byte voor je terminatie '\0' :7

Ik begrijp trouwens niet waarom je dit niet in een simpele NT command file steekt met 1 for loopje :?

Verwijderd

Topicstarter
Alle code staat onder een knop. Ik lees eerst in een array (alleCFGs[i][0])een aantal bestandsnamen in. Het is de bedoeling dat de bestandsnamen in deze array 1 voor 1 achter het sjabloon geplakt worden en dan die totale string op de cmdline uitgevoerd worden. Er mag dus geen enkel extra karacter of spatie bij komen.

Met deze code krijg ik een Access Violation en heeft te maken met de declaratie van tmp. Maar als ik daar dan tmp[100] van maak heb ik er karakters bij staan die ik niet wil.

Het is toch zo dat je met call by value een variabele in de aanroepende omgeving niet veranderd. Ik heb het met integers geprobeerd en dan werkt het wel. Maar dat zijn dan weer geen arrays, daar zal wel een probleem liggen. Maar ik zie het niet.

Mijn vraag is dus: Hoe gebruikt ik een string (array van chars) als sjabloon, zonder dat er in de werkruimte (de variabele tmp) karakters komen die ik niet wil.

Verwijderd

tip : veeg het stof van je leerboeken . .. haal de verpakking eraf .. en reserveer de rest van de dag voor LEZEN...

  • whoami
  • Registratie: December 2000
  • Laatst online: 07-09 19:30
arrays (dus ook pointers naar char's) van gelijk welk type worden per definitie by reference doorgegeven en niet by value.

Als je ze doorgeeft naar een functie, geef die die niet mogen veranderen dan eens door als const.

zo bv:
code:
1
char* MaakStringVanStrings(const char* Sjabloon);

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ik begrijp trouwens niet waarom je dit niet in een simpele NT command file steekt met 1 for loopje :?
:? Nou als dat handiger is wil ik dat best doen, het zegt me alleen helemaal niets. Een for loop natuurlijk wel maar dat NT command file niet.

Verwijderd

Topicstarter
Op woensdag 22 mei 2002 11:03 schreef Skizmo het volgende:
tip : veeg het stof van je leerboeken . .. haal de verpakking eraf .. en reserveer de rest van de dag voor LEZEN...
Wat denk je wat ik naast me heb liggen. Er zitten aantekeningen bij van 1997. :)

  • whoami
  • Registratie: December 2000
  • Laatst online: 07-09 19:30
Je zit trouwens over call by value enzo te praten, maar ik zie nergens een functie staan in de code die je gepost hebt. Hoe kun je dan spreken over call by value enzo ?

https://fgheysels.github.io/


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 07-09 08:58
Op woensdag 22 mei 2002 10:39 schreef knien001 het volgende:
Ik heb 2 string pointers waarvan ik 1 als werkruimte (tmp) gebruik en 1 als sjabloon (sjabloon). Het is dus de bedoeling dal alleen de werkruimte veranderd en het sjabloon niet.

{
char *tmp;[ SNIP ]
Wie ziet waar ik de fout in ga?
Ongeveer bij de char*.

Gebruik gewoon std::string; die heeft een normale +, geen memory problemen meer.

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


Verwijderd

Topicstarter
Op woensdag 22 mei 2002 11:09 schreef whoami het volgende:
Je zit trouwens over call by value enzo te praten, maar ik zie nergens een functie staan in de code die je gepost hebt. Hoe kun je dan spreken over call by value enzo ?
Dat heb ik hier in mijn boek staan en toen ik het las dacht ik dit moet ik hebben. Ik heb dit wel allemaal geleerd maar een tijd niet gebruikt dus nu een beetje roestig. Maar het begint allemaal weer een beetje te dagen.

ik heb nu een functie gemaakt zoals je aangaf en zo te zien werkt het nu. Heel erg bedankt *D.

Dit is de functie die ik nu heb staan:

char* MaakStringVanStrings(const char* Sjabloon, int i)
{
char *tmp;

tmp=(char*)calloc(strlen(Sjabloon)+strlen(alleCFGs[i][0])+1,sizeof(char));
strcpy(tmp,Sjabloon);
strcat(tmp,alleCFGs[i][0]);
return(tmp);
}

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 06-09 22:39
En waar free(...) je tmp weer ? ;)

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.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

whoami:
arrays (dus ook pointers naar char's) van gelijk welk type worden per definitie by reference doorgegeven en niet by value.
pointers zelf worden niet by reference meegegeven ;)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:44

.oisyn

Moderator Devschuur®

Demotivational Speaker

idd, daarvoor moet je bij deze topic zijn: [topic=499840] ;)

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.


  • whoami
  • Registratie: December 2000
  • Laatst online: 07-09 19:30
Op woensdag 22 mei 2002 13:23 schreef drm het volgende:

[..]

pointers zelf worden niet by reference meegegeven ;)
Maar een tabel van characters zoals:
code:
1
char tabel[10];

is toch hetzelfde als:
code:
1
char* tabel = new char[10];

Want, als je doet
code:
1
cout << tabel;

krijg je toch het beginadres (het adres van het 0-de element) van de array?

Of spreken we hier van Babylonische spraakverwarring?

https://fgheysels.github.io/


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:44

.oisyn

Moderator Devschuur®

Demotivational Speaker

een char tabel[10] is totaal niet hetzelfde als een char * tabel = new char[10]

bij de pointer heeft tabel zelf geheugenruimte van 4 bytes, waar de waarde in staat waar hij naar wijst. Daar is tabel op zich ook gewoon een variabele (en wordt dus ook by value naar functies gestuurd). sizeof (tabel) geeft hier 4

Bij de array is tabel geen fysieke variabele, maar de hele array. Een sizeof (tabel) geeft hier dan ook 10 * sizeof (char). Het symbool tabel kun je echter wel gewoon converteren naar een char *, maar het is geen char *

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.


  • whoami
  • Registratie: December 2000
  • Laatst online: 07-09 19:30
Dus, als ik het nu goed begrijp zou volgende code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void PointerTest(char*);

void main()
{

char* blaat = "Test";
PointerTest(blaat);
cout << blaat;

}

void PointerTest(char* tmp)
{
  strcpy(tmp, "aaa");
}

als output test hebben?

En als ik nu die functie als PointerTest("blaat") zou aanroepen? Hoe gaat dit dan? Wordt die "blaat" aanzien als een char* of een char[]?

https://fgheysels.github.io/


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

whoami:
Dus, als ik het nu goed begrijp zou volgende code:
code:
1
snip

als output test hebben?
Nee, je begrijpt het verkeerd. Een pointer zelf is een geheugenadres. Dit adres wordt meegegeven, niet de inhoud van het adres. Dat is nou precies wat by-reference is, omdat je een reference aan X meegeeft aan de functie, die dus vervolgens weet waar X staat in het geheugen. Maar de pointer zelf, de waarde van het geheugenadres, dus, wordt dus niet by reference meegegeven. oftewel:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void f ( char *ch )
{
   ch ++;
}

char *array = new char[2];
array[0] = 'a';
array[1] = 'b';

// hier wordt dus het adres van array[0] meegegeven
// maar by-value en niet by-reference. array[0] wordt
// echter by reference meegegeven, omdat ik daar het adres
// van meegeef
f ( & ( array[0] ) );

printf ( "%c", array [0] );

geef als output
code:
1
a

en niet
code:
1
b

snappie?

Da's het idee.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 06-09 22:39
Op woensdag 22 mei 2002 14:07 schreef whoami het volgende:
code:
1
char* blaat = "Test";
Normaal gesproken is het niet toegestaan om naar een const char * te schrijven. Je moet dan een char blaat[]="Test" declareren.

Niet dat dat hier terzake doet, maargoed ... :)

[edit]
Er zijn meer mensen die er zo over denken ;)

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.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 07-09 08:58
Op woensdag 22 mei 2002 14:07 schreef whoami het volgende:
Dus, als ik het nu goed begrijp zou volgende code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void PointerTest(char*);

void main()
{

char* blaat = "Test";
PointerTest(blaat);
cout << blaat;

}

void PointerTest(char* tmp)
{
  strcpy(tmp, "aaa");
}

als output test hebben?

En als ik nu die functie als PointerTest("blaat") zou aanroepen? Hoe gaat dit dan? Wordt die "blaat" aanzien als een char* of een char[]?
Het resultaat is onvoorspelbaar.
Een "string" tussen "" is een char const[].
Als je een char const[] gebruikt waar je een char*
nodig hebt, dan wordt de pointer gezet naar het eerste
element. De const die weggemoffeld wordt is voor C compabiliteit. Maar omdat je probeert naar deze
const chars te schrijven wordt je source code
(potentieel) overschreven, waardoor je programma
kan crashen, HD formatten, etc.

Had je char blaat[]="text" geschreven, dan was blaat
een array geworden van 5 non-const chars. Als je
dat past (als char*) dan probeer je "aaa" (4 karakters) te kopieren naar het begin van die 5 chars. Je eindigt dan dus met de 5 chars aaa\0\0.

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


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

MSalters:
[Een hoop]
En dat is idd de andere kant van het verhaal :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Verwijderd

Topicstarter
Op woensdag 22 mei 2002 13:03 schreef farlane het volgende:
En waar free(...) je tmp weer ? ;)
Dat hoet toch niet. Als ik uit de scoop van de fuctie ga bestaat tmp toch niet meer.

  • whoami
  • Registratie: December 2000
  • Laatst online: 07-09 19:30
Als je iets op de heap alloceert moet je imho toch alles freeën als je het niet meer nodig hebt?

dus : delete[] tmp doen.

https://fgheysels.github.io/


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 06-09 22:39
Op woensdag 22 mei 2002 16:17 schreef knien001 het volgende:
Dat hoet toch niet. Als ik uit de scoop van de fuctie ga bestaat tmp toch niet meer.
tmp niet meer nee, maar je gereserveerde geheugen blijft gereserveerd als je deze niet vrijgeeft.

Je pointer naar dat geheigen geef je terug uit de functie dus het is goed mogelijk om het netjes weer te free(...) en.

[edit]
En itt wat whoami zegt kun je beter niet delete gebruiken als je malloc of calloc gebruikt. ;)

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.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

knien001:
Dat hoet toch niet. Als ik uit de scoop van de fuctie ga bestaat tmp toch niet meer.
En daar hebben we de grote fout, de oorsprong van vele memory-leaks in c++ programma's ;)
whoami:
Als je iets op de heap alloceert moet je imho toch alles freeën als je het niet meer nodig hebt?
ja dus :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:44

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op woensdag 22 mei 2002 14:07 schreef whoami het volgende:
Dus, als ik het nu goed begrijp zou volgende code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void PointerTest(char*);

void main()
{

char* blaat = "Test";
PointerTest(blaat);
cout << blaat;

}

void PointerTest(char* tmp)
{
  strcpy(tmp, "aaa");
}

als output test hebben?

En als ik nu die functie als PointerTest("blaat") zou aanroepen? Hoe gaat dit dan? Wordt die "blaat" aanzien als een char* of een char[]?
misschien een beetje mosterd na de maaltijd, maar ik zeg het toch :)

Jij verbindt tmp met waar ie naar toe wijst; dat moet je niet doen. Kijk dit voorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void func1 (int i)
{
    i = 3;
}

void func2 (int & i)
{
    i = 3;
}

int main ()
{
    int i = 2;
    func1 (i); // hierna is i nog steeds 2
    func2 (i); // hierna is i 3
}

naar func1 wordt i by value verstuurd, bij func2 by reference. Bij func1 wordt dus een kopie gemaakt van i en dat gepushed op de stack, bij func2 wordt een referentie naar i op de stack gepushed (de onderliggende implementatie is in principe net als een pointer). func1 (3) kan wel, func2 (3) kan niet (3 is immers gewoon een waarde, het heeft geen stukje geheugen waar het in staat, en dus kan er geen referentie worden meegestuurd)

kijk nu even hiernaar:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
typedef const char * ptr;

void func1 (ptr s)
{
    s = "blaat";
}

void func2 (ptr & s)
{
    s = "blaat";
}

int main ()
{
    ptr s = "plop";
    func1 (s); // s wijst nog steeds naar "plop"
    func2 (s); // s wijst nu naar "blaat"
}

Die typedef heb ik even gedaan om duidelijk te maken wat by value wordt doorgestuurd, en wat by reference
In principe staat hier precies hetzelfde:
code:
1
2
3
4
5
6
7
8
9
void func1 (const char * s)
{
    s = "blaat";
}

void func2 (const char *& s)
{
    s = "blaat";
}

func1 dus by value, func2 by reference. Terwijl je te maken hebt met een pointer (maar de pointer an sich is nog steeds een variabele)
code:
1
2
3
4
5
6
7
8
9
10
11
char * tmp1 = new char[10];
char tmp2[10];

func1 (tmp1); // werkt prima

func2 (tmp1); // idem, maar tmp1 wijst nu niet meer naar
          // z'n gealloceerde buffer
func1 (tmp2); // werkt prima, hij wordt gecast naar const char *

func2 (tmp2); // FOUT! tmp2 is geen const char *, je kunt m
          // dus ook niet assignen naar een andere waarde

ik hoop dat het nu duidelijk is :)

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.


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 06-09 22:39
void func1 (const char * s)
{
s = "blaat";
}
Gaat dat geen compilerfout opleveren?

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.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 07-09 08:58
Op woensdag 22 mei 2002 17:59 schreef farlane het volgende:
code:
1
2
3
4
void func1 (const char * s)
{
s = "blaat";
}

Gaat dat geen compilerfout opleveren?
Zoals?
Een programmafout, waarschijnlijk wel ja. Net zoiets als
code:
1
2
3
void func1( int i ) {
  i = 5; // Tsja.
}

offtopic:
intikken en vervolgens afwachten todat je //comment groen wordt. :Z Hoezo teveel lopen coden vandaag ?

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


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

MSalters:
Zoals?
Een programmafout, waarschijnlijk wel ja. Net zoiets als
code:
1
2
3
void func1( int i ) {
  i = 5; // Tsja.
}
Daar is niets mis mee :? functioneel beetje zinloos, maar goed, 't is niet fout.
offtopic:
intikken en vervolgens afwachten todat je //comment groen wordt. :Z Hoezo teveel lopen coden vandaag ?
Wheheheh rotflol :D

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:44

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op woensdag 22 mei 2002 17:59 schreef farlane het volgende:

[..]

Gaat dat geen compilerfout opleveren?
nee waarom?
de data waar s naar wijst is const, maar s zelf niet

in tegensteling tot bijvoorbeeld deze functie:
code:
1
2
3
4
5
void func (char * const s)
{
    s = "blaat"; // fout! s is constant
    s[0] = 'd';  // ok, de data waar s naar wijst is niet const
}

(ervan uitgaande dat s naar goede data wijst bij aanroep ;))

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.


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 06-09 22:39
Op woensdag 22 mei 2002 20:37 schreef .oisyn het volgende:
...de data waar s naar wijst is const, maar s zelf niet...
Da's waar, was me ff ontschoten hoe de volgorde van lezen ook al weer moest zijn.

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.


  • whoami
  • Registratie: December 2000
  • Laatst online: 07-09 19:30
[off-topic mode]
Bijzonder toch hoe die -soms eenvoudige C++ topics- altijd uitgroeien naar zeer interessante discussies. :)
[/off-topic mode]

https://fgheysels.github.io/


Verwijderd

Topicstarter
Op donderdag 23 mei 2002 10:46 schreef whoami het volgende:
[off-topic mode]
Bijzonder toch hoe die -soms eenvoudige C++ topics- altijd uitgroeien naar zeer interessante discussies. :)
[/off-topic mode]
Inderdaad ja. Maar het heeft levert wel nuttige info op, zoals het freeen van het geheugen. Daar had ik niet aan gedacht. :)
Pagina: 1