/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Call-by-reference (char*)
Fra : Hans Odborg


Dato : 08-12-03 23:41

Jeg vil gerne lave Call-by-reference så jeg ka få 2 char* skrevet med
eet funktionskald ala:


void call_func(char *out_version, char *rparam){
out_version="2.4";
rparam="SUBJ";
}


jeg kalder:

char *ret1;
char *ret2;
call_func(ret1, ret2)


men bagefter indeholder ret1 kun underlige ting og tilgang til ret2 får
programmet til at segfault'e.

Hvad gør jeg galt?


 
 
Bertel Brander (09-12-2003)
Kommentar
Fra : Bertel Brander


Dato : 09-12-03 00:08

Hans Odborg wrote:

> Jeg vil gerne lave Call-by-reference så jeg ka få 2 char* skrevet med
> eet funktionskald ala:
>
>
> void call_func(char *out_version, char *rparam){
> out_version="2.4";
> rparam="SUBJ";
> }
>
>
> jeg kalder:
>
> char *ret1;
> char *ret2;
> call_func(ret1, ret2)
>
>
> men bagefter indeholder ret1 kun underlige ting og tilgang til ret2 får
> programmet til at segfault'e.
>
> Hvad gør jeg galt?
>
I C:

#include <stdio.h>

void call_func(char **out_version, char **rparam){
*out_version="2.4";
*rparam="SUBJ";
}

int main(void)
{
char *ret1;
char *ret2;
call_func(&ret1, &ret2);

printf("%s %s", ret1, ret2);
return 0;
}

I C++:
#include <iostream>

void call_func(char *&out_version, char *&rparam)
{
out_version="2.4";
rparam="SUBJ";
}


int main(void)
{
char *ret1;
char *ret2;
call_func(ret1, ret2);

std::cout << ret1 << ", " << ret2 << std::endl;
return 0;
}

/b


Bertel Lund Hansen (09-12-2003)
Kommentar
Fra : Bertel Lund Hansen


Dato : 09-12-03 00:23

Bertel Brander skrev:

>I C:

>void call_func(char **out_version, char **rparam){
> *out_version="2.4";
> *rparam="SUBJ";
>}

>int main(void)
>{
> char *ret1;
> char *ret2;
> call_func(&ret1, &ret2);
>
> printf("%s %s", ret1, ret2);
> return 0;
>}

Er det ikke en skjult måde at allokere hukommelse på i
funktionen?

Hvis jeg har ret, hvad så med hukommelsesspild?

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

Mogens Hansen (09-12-2003)
Kommentar
Fra : Mogens Hansen


Dato : 09-12-03 05:41


"Bertel Lund Hansen" <nospamius@lundhansen.dk> wrote: in message
news:ct1atvcgl267i4tsu578kkf4u1r57lkvrj@news.stofanet.dk...
> Bertel Brander skrev:
>
> >I C:
>
> >void call_func(char **out_version, char **rparam){
> > *out_version="2.4";
> > *rparam="SUBJ";
> >}
>
> >int main(void)
> >{
> > char *ret1;
> > char *ret2;
> > call_func(&ret1, &ret2);
> >
> > printf("%s %s", ret1, ret2);
> > return 0;
> >}
>
> Er det ikke en skjult måde at allokere hukommelse på i
> funktionen?

Nej - det er blot en peger "const array of char".
Der står ikke new eller malloc nogen steder.

Dog bør det rettelig være en "const char*" idet den ikke kan ændres.

>
> Hvis jeg har ret, hvad så med hukommelsesspild?

Ikke et problem her.
(Men der lurer ofte problemer i nærheden - brug std::string)

Venlig hilsen

Mogens Hansen



Hans Odborg (09-12-2003)
Kommentar
Fra : Hans Odborg


Dato : 09-12-03 15:25

Men hvorfr virker det pludseligt når der kommer en ekstra pointer på det
hele?
(ps. bruger C ikke C++)

Mogens Hansen wrote:
> "Bertel Lund Hansen" <nospamius@lundhansen.dk> wrote: in message
> news:ct1atvcgl267i4tsu578kkf4u1r57lkvrj@news.stofanet.dk...
>
>>Bertel Brander skrev:
>>
>>
>>>I C:
>>
>>>void call_func(char **out_version, char **rparam){
>>> *out_version="2.4";
>>> *rparam="SUBJ";
>>>}
>>
>>>int main(void)
>>>{
>>> char *ret1;
>>> char *ret2;
>>> call_func(&ret1, &ret2);
>>>
>>> printf("%s %s", ret1, ret2);
>>> return 0;
>>>}
>>
>>Er det ikke en skjult måde at allokere hukommelse på i
>>funktionen?
>
>
> Nej - det er blot en peger "const array of char".
> Der står ikke new eller malloc nogen steder.
>
> Dog bør det rettelig være en "const char*" idet den ikke kan ændres.
>
>
>>Hvis jeg har ret, hvad så med hukommelsesspild?
>
>
> Ikke et problem her.
> (Men der lurer ofte problemer i nærheden - brug std::string)
>
> Venlig hilsen
>
> Mogens Hansen
>
>


Bertel Brander (09-12-2003)
Kommentar
Fra : Bertel Brander


Dato : 09-12-03 20:23

Hans Odborg wrote:
> Men hvorfr virker det pludseligt når der kommer en ekstra pointer på det
> hele?
> (ps. bruger C ikke C++)
>

I C er der (til forskel fra C++) ikke noget der hedder
call-by-reference, det er altid call-by-value.
Man kan godt kalde med en pointer, men pointeren bliver overført
som value.


Hvis man har:

T x;

f(x);

vil f() modtage et kopi af x. Hvis f() ændrer på værdien den
modtager vil den således ændre kopien.

Hvis vi vil have f til at ændre x (og ikke kopien af x) må
vi give f() en pointer til x (eller rettere et kopi af en
pointer til x):

f(&x);

&x er en pointer til x, så hvis vi har en f() der ser ud som følger:

void f(T *v)
{
*v = 7;
}

Vil f() ændre i det v peger på, hvilket i dette tilfælde var x.

Hvis T f.ex. er en int:

void f(int *v)
{
*v = 7;
}
....
int x;
f(&x);

vil f() sætte x til at være 7.


I dit tilfælde ville du have call_func() til at ændre
på indholdet af ret1 og ret2, disse var af typen char *.
Så vi kan erstatte T i ovenstående med char *.

Så hvis vi har (som i dit oprindelige kode):

f(char *v)
{
v = "Test";
}

char *x;
f(x);

Vil f() modificere kopien af x, det var ikke det vi ønskede,
vi ønskede at ændre på x, så vi må give f en pointer til x,
dvs. en char **:

f(char **v)
{
*v = "Test";
}

char *x;
f(&x);


HTH

/b


Bertel Brander (10-12-2003)
Kommentar
Fra : Bertel Brander


Dato : 10-12-03 23:31

Bertel Brander wrote:
> I C er der (til forskel fra C++) ikke noget der hedder
> call-by-reference, det er altid call-by-value.

Ved nærmere eftertanke; er der call-by-reference i C++?

Man har ganske vist referencer, men gør det vil ikke til
call-by-reference. Er det ikke blot en reference overført
som value?

/b


Lasse Westh-Nielsen (10-12-2003)
Kommentar
Fra : Lasse Westh-Nielsen


Dato : 10-12-03 23:53

"Bertel Brander" <bertel@post4.tele.dk> wrote in message
news:3fd79d28$0$170$edfadb0f@dread11.news.tele.dk...
> Bertel Brander wrote:
> > I C er der (til forskel fra C++) ikke noget der hedder
> > call-by-reference, det er altid call-by-value.
>
> Ved nærmere eftertanke; er der call-by-reference i C++?
>
> Man har ganske vist referencer, men gør det vil ikke til
> call-by-reference. Er det ikke blot en reference overført
> som value?


Joo, men du skal jo overføre et eller andet

Call by value betyder vel bare, at man tager en kopi af sin variabel, når
man kalder en funktion. Så kan man lave om på variablen i funktionskaldet,
uden at originalen ændres.

Call be reference betyder, at du overfører variablen selv, således at de
ændringer du foretager i et funktionskald reflekteres i originalen.

Så i call by reference overfører du værdien af referencen...

- Lasse


--
Lasse Westh-Nielsen
lasse@daimi.au.dk




Bertel Brander (11-12-2003)
Kommentar
Fra : Bertel Brander


Dato : 11-12-03 20:45

Lasse Westh-Nielsen wrote:
> "Bertel Brander" <bertel@post4.tele.dk> wrote in message
> news:3fd79d28$0$170$edfadb0f@dread11.news.tele.dk...
>
>>Bertel Brander wrote:
>>
>>>I C er der (til forskel fra C++) ikke noget der hedder
>>>call-by-reference, det er altid call-by-value.
>>
>>Ved nærmere eftertanke; er der call-by-reference i C++?
>>
>>Man har ganske vist referencer, men gør det vil ikke til
>>call-by-reference. Er det ikke blot en reference overført
>>som value?
>
>
>
> Joo, men du skal jo overføre et eller andet
>
> Call by value betyder vel bare, at man tager en kopi af sin variabel, når
> man kalder en funktion. Så kan man lave om på variablen i funktionskaldet,
> uden at originalen ændres.
>
> Call be reference betyder, at du overfører variablen selv, således at de
> ændringer du foretager i et funktionskald reflekteres i originalen.
>
> Så i call by reference overfører du værdien af referencen...
>

Det jeg mente var, at nogle sprog har en speciel syntax til at
lave call-by-reference

Så vidt jeg husker kunne man i Turbo Pascal skrive:

procedure foo (var x : integer)

eller

procedure bar (z : integer)


så ville x blive overført som en reference og z som en value.

/b


Kent Friis (11-12-2003)
Kommentar
Fra : Kent Friis


Dato : 11-12-03 22:17

Den Thu, 11 Dec 2003 20:45:01 +0100 skrev Bertel Brander:
>
>Det jeg mente var, at nogle sprog har en speciel syntax til at
>lave call-by-reference
>
>Så vidt jeg husker kunne man i Turbo Pascal skrive:
>
>procedure foo (var x : integer)
>
>eller
>
>procedure bar (z : integer)
>
>
>så ville x blive overført som en reference og z som en value.

Og i C++ skriver man

void foo(int & x)

eller

void foo(int z)

Syntax'en er en anden (& i stedet for var), resultatet er det samme.

Mvh
Kent
--
Help test this great MMORPG game - http://www.eternal-lands.com/

Bertel Lund Hansen (09-12-2003)
Kommentar
Fra : Bertel Lund Hansen


Dato : 09-12-03 00:20

Hans Odborg skrev:

>Jeg vil gerne lave Call-by-reference så jeg ka få 2 char* skrevet med
>eet funktionskald ala:

Jeg går ud fra at du bruger ren C.

>void call_func(char *out_version, char *rparam){
> out_version="2.4";
Nu peger out_version på konstanten "2.4".
> rparam="SUBJ";
Nu peger rparam på konstanten "SUBJ".
>}
Og nu blev begge disse konstanter nedlagt så out_version og
rparam er udefinerede (og dermed også ret1 og ret2).

Det løses ved at allokere hukommelse (nok) til ret1 og ret2 før
kaldet og så bruge strcpy() i funktionen.

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

Byrial Jensen (09-12-2003)
Kommentar
Fra : Byrial Jensen


Dato : 09-12-03 21:36

Bertel Lund Hansen wrote:
> Hans Odborg skrev:
>
>>void call_func(char *out_version, char *rparam){
>> out_version="2.4";
>
> Nu peger out_version på konstanten "2.4".

Ja.

>> rparam="SUBJ";
>
> Nu peger rparam på konstanten "SUBJ".

ja.

>>}
>
> Og nu blev begge disse konstanter nedlagt

Nej. Strengkonstanter er statisk allokerede og lever derfor lige så
længe som programmet kører.

> så out_version og rparam er udefinerede

out_version og rparam ophører med at eksistere når funktionen forlades,
men det de pegede på, vil fortsat eksistere.

> (og dermed også ret1 og ret2).

ret1 og ret2 er ikke ændrede da er overført "by value".

> Det løses ved at allokere hukommelse (nok) til ret1 og ret2 før
> kaldet og så bruge strcpy() i funktionen.

Det er simplere at overføre pointere til ret1 og ret2 til den kaldte
funktion så deres værdier kan ændres af funktionen til at pege på
strengkonstanterne.


Søg
Reklame
Statistik
Spørgsmål : 177549
Tips : 31968
Nyheder : 719565
Indlæg : 6408820
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste