Gå til innhold

call by ref. på array oppfører seg som call by val.


Anbefalte innlegg

etter å ha brukt lørdagskvelden på kode som ikke fungerte, kokte probelmet ned til:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 void map(float* data){
 4	 data = (float*)malloc(10*sizeof(float));
 5	 for(int i=0; i < 10; i++){
 6		 data[i] = (float)i;
 7		 printf("%f\n",data[i]);
 8	 }
 9	 printf("\n\n");
10 }
11 
12 int main(int arg, char* argv[]){
13	 float* data;
14	 map(data);
15	 for(int i=0; i < 10; i++){
16		 printf("%f\n",data[i]);
17	 }
18	 //free(data);
19	 return 0;
20 };

dette gir ti linjer stigende desimaltall og ti linjer garbage. hvis jeg kommenterer ut free på linje 18 får jeg segfault.

 

Det er tydelig at dataene i map() forsvinner når de forlater scopet til map(). I min verden er data en peker, og skal derfor ikke arbeide på "lokale kopier". I praksis fungerer sånn. Hvorfor det?

Lenke til kommentar
Videoannonse
Annonse

void map(float* data){
 4	 data = (float*)malloc(10*sizeof(float));

 

Du endrer verdien på pekeren som du leser inn med en gang, dette parameteret er poengløst, da du endrer det med en gang allikevel.

 

Skal du returnere et nytt array som parameter, må du gjøre dette om til en float **

 

Når du skrive void map(float *data) er dette det samme som void map(pointer data)

 

Og hvis du da kaller funksjonen med f.eks. map(250) og deretter kaller

data = 100; f.eks. så spiller det ingen rolle hvilken verdi dette var i utgangspunktet hvis du skjønner.

 

Derfor er det to muligheter:

 

Returner array fra funksjonen, eller bruk pointer to pointer:

 

void map(float** data)
{
 *data = (float*)malloc(10*sizeof(float));
 for(int i=0; i < 10; i++)
 {
(*data)[i] = (float)i;
printf("%f\n",data[i]);
 }
 printf("\n\n");
}

int main(int arg, char* argv[])
{
 float* data;
 map(&data);
 for(int i=0; i < 10; i++)
 {
printf("%f\n",data[i]);
 }
 free(data);
 return 0;
}

 

edit: dessuten skal det ikke være semikolon etter en funksjon ;) (int main)

Endret av GeirGrusom
Lenke til kommentar
etter å ha brukt lørdagskvelden på kode som ikke fungerte, kokte probelmet ned til:

...

dette gir ti linjer stigende desimaltall og ti linjer garbage. hvis jeg kommenterer ut free på linje 18 får jeg segfault.

 

Det er tydelig at dataene i map() forsvinner når de forlater scopet til map(). I min verden er data en peker, og skal derfor ikke arbeide på "lokale kopier". I praksis fungerer sånn. Hvorfor det?

 

Når du sender float* til map blir data en lokal kopi og har ingen tilknytning til data i main.

For å få til det det virker som om du vil må du bruke en peker til peker. Så du sender en peker til data (som er en peker til float). Map kan da bruke pekeren til data for å finne ut hvor data holder til, så kan map skriver addressen til det nylig allokerte minne til data.

Tilbake i main vil data ha forandre seg og du kan deallokerer data.

Slik som koden din over fungere så vil den prøve og deallokere et helt random sted av minne.

 

Regner med at det er noe slik du prøvde på.

For din egen del ville jeg prøvd å forstå hva jeg prøver å forklare og gjerne lage din egen løsning på problemet før du kikket på koden under, still gjerne flere spørsmål for å oppklare uklarheter som sikkert finnes ;)

 

 

#include <stdio.h>
#include <stdlib.h>

void map(float** data)
{
(*data) = (float*)malloc(10*sizeof(float));
for(int i=0; i < 10; i++)
{
	(*data)[i] = (float)i;
	printf("%f\n",data[i]);
}
printf("\n\n");
}

int main(int arg, char* argv[])
{
float* data;
map(&data);
for(int i=0; i < 10; i++)
{
	printf("%f\n",data[i]);
}
free(data);
return 0;
}

 

 

 

 

Edit:.... darn slått av gg på minuttet, nesten skremmende hvor like koden er... men min fungere :D

Endret av Giddion
Lenke til kommentar

Så sånn jeg ser det brukes pekere til to ting i c(++): for å representere arrays og for å oppnå "call by reference".

Hvis jeg er interessert i å call by reference til en array må jeg altså dobbeltpeke.

Er jeg inne på noe? I såfall tror jeg at jeg har skjønt det, og da ville:

 

void mapToTen(int* pnt){

*pnt = 10;

}

 

vært synlig utenfor funksjonen :)

 

takk for hjelp

Lenke til kommentar

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...