Avatar billede n1ghtmr Nybegynder
13. marts 2005 - 17:07 Der er 12 kommentarer og
1 løsning

Pointers som argument til en funktion

Jeg sidder lidt og prøver at forstå pointere fuldt ud i C. Jeg har denne kode:

int *p;

p = (int*)malloc(sizeof(int));
if (p == NULL) fatalerror(...);
free(p);

Dette virker fint. Hvis jeg nu prøver det samme med funktioner altså:

int main()
{
  int *p;
  init(p);
  destroy(p);
}

void init(int *p)
{
  p = (int*)malloc(sizeof(int));
  if (p == NULL) fatalerror("..");
}

void destroy(int *p)
{
  free(p);
}

Får jeg en fejl når jeg kører min applikation. Nogle ideér til hvad det kan skyldes?

Mvh. Nmare
Avatar billede bromer Nybegynder
13. marts 2005 - 17:18 #1
Hvilken fejl faar du? Uden at jeg lige har en compiler ved mig, skal du vist ikke dereferer p parameteren i init funktionen.
Avatar billede n1ghtmr Nybegynder
13. marts 2005 - 17:41 #2
Segmention fault.
Avatar billede bertelbrander Novice
13. marts 2005 - 18:12 #3
Hvis en funktion skal kunne modificere et argument så den der kalder funktionen kan se det må man give funktionen en pointer (eller reference) til variablen;

void f(TYPE *i)
{
  *i = whatever;
}

Hvis man giver f en normal variabel vil den modificere sin kopi af variablen.

I dit tilfælde er TYPE en int *, så din init skal have en pointer til en int *:
void init(int **p)
{
  *p = (int*)malloc(sizeof(int));
  if (*p == NULL) fatalerror("..");
}

int main()
{
  int *p;
  init(&p);
  destroy(p);
}

Destroy behøver ikke få en int **, den modificerer ikke pointeren.
Avatar billede arne_v Ekspert
13. marts 2005 - 18:45 #4
Et alternativ ville være:

int *init()
Avatar billede arne_v Ekspert
13. marts 2005 - 18:46 #5
Eller nok snarere:

void init(int n,int **p)

og

int *init(int n)
Avatar billede n1ghtmr Nybegynder
14. marts 2005 - 15:31 #6
Ok det virker fint nok. Dvs. hvis jeg nu startede med en int i i stedet for int *i ville det vaare:

int main()
{
  int p;
  init(&p);
  destroy(&p);
}

void init(int *p)
{
  p = (int*)malloc(sizeof(int));
  if (p == NULL) fatalerror("..");
}

void destroy(int *p)
{
  free(p);
}
Avatar billede n1ghtmr Nybegynder
14. marts 2005 - 15:32 #7
Hm, fejl, prover lige igen :)

int main()
{
  int p;
  init(&p);
  destroy(&p);
}

void init(int *p)
{
  p = (int*)malloc(sizeof(int));
  if (p == NULL) fatalerror("..");
}

void destroy(int *p)
{
  free(&p);
}
Avatar billede arne_v Ekspert
14. marts 2005 - 15:46 #8
Hvad prøver du ?

At have en int* i en int ?
Avatar billede n1ghtmr Nybegynder
14. marts 2005 - 16:00 #9
Jeg vil gerne starte med en int p (ift. for hvor jeg for havde en int *p) og saa lave en init og destroy funktion der har typen init(int *p) og destroy(int *p). Udfra bertels eksempel ville jeg tro det blot var at gaa et skridt "tilbage" (altsa **p = *p og *p = p) men saa giver free fejl.
Avatar billede arne_v Ekspert
14. marts 2005 - 19:00 #10
så skal du bruge destroy(int p), men det er efter min bedste overbevisning
en dårlig ide

malloc returnerer en pointer - det er ganske vidt muligt at gemme en pointer i en int,
men det er absolut ikke anbefalelsesværdigt
Avatar billede bertelbrander Novice
14. marts 2005 - 22:56 #11
Det giver ikke rigtigt mening at sætte p (en int) til at være resultatet af en malloc, det du prøver er det samme som:

int p = (int *)malloc(sizeof(int));
free(p);

Hvis ikke i skal være en pointer kunne man lave:

#include <stdio.h>
void init(int *p)
{
  *p = 123;
}
void init2(int p)

{
  p = 444;
}

int main()
{
  int p = 0;
  printf("Before Init: %d\n", p);
  init(&p);
  printf("After Init: %d\n", p);
  init2(p);
  printf("After Init2: %d\n", p);
}

Bemærk at p (i main) er 123 efter init() og også 123 efter init2.
Avatar billede n1ghtmr Nybegynder
15. marts 2005 - 19:01 #12
virker nu. Dem der vil have point kan lægge svar
Avatar billede arne_v Ekspert
15. marts 2005 - 20:23 #13
Det er vel Bertel der har trukket det tunge læs, men et kig i min glas kugle
siger at han nok ikke vil have point, så ...
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