Question

Je pense que je l'ai compris dans le cas le plus fondamental:

int main(int argc, char ** argv) {
  int * arr;

  foo(arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int * arr) {
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
}

La sortie est la suivante:

> ./a.out 
 car[3]=-1869558540
 a.out(4100) malloc: *** error for object 0x8fe01037: Non-aligned pointer
                         being freed
 *** set a breakpoint in malloc_error_break to debug
>

Si quelqu'un peut nous éclairer sur les points faibles de ma compréhension, ce serait grandement apprécié.

Était-ce utile?

La solution

Vous passez le pointeur par valeur, et non par référence. Ainsi, quoi que vous fassiez avec arr à l'intérieur de foo ne fera aucune différence en dehors de la fonction foo. Comme m_pGladiator a écrit, une façon est de déclarer une référence à un pointeur comme ceci (uniquement possible en C ++, C ne sait pas à propos des références):

int main(int argc, char ** argv) {
  int * arr;

  foo(arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int * &arr ) {
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
}

Une autre façon (mieux, à mon humble avis) est de ne pas passer le pointeur sous forme d'argument, mais de renvoyer un pointeur:

int main(int argc, char ** argv) {
  int * arr;

  arr = foo();
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

int * foo(void ) {
  int * arr;
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
  return arr;
}

Et vous pouvez passer un pointeur à un pointeur. C'est la façon de passer en C par référence. Complique un peu la syntaxe, mais c’est comme ça que C est ...

int main(int argc, char ** argv) {
  int * arr;

  foo(&arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int ** arr ) {
  (*arr) = (int*) malloc( sizeof(int)*25 );
  (*arr)[3] = 69;
}

Autres conseils

Vous avez alloué arr in foo, mais cette valeur de pointeurs est stockée dans la pile d'appels. Si vous souhaitez le faire, procédez comme suit:

void foo( int ** arr) {
    *arr = (int *)malloc( sizeof(int) * 25 );
    (*arr)[3] = 69;
}

Et dans le menu principal, passez simplement un pointeur sur foo (comme foo (& amp))

foo reçoit une copie locale du pointeur int, y alloue de la mémoire et la perd quand cette dernière s’étend.

Un moyen de résoudre ce problème pour que foo renvoie le pointeur:

int * foo() {
  return (int*) malloc( sizeof(int)*25 );
}

int main() {
    int* arr = foo();
}

Une autre consiste à passer foo un pointeur à un pointeur

void foo(int ** arr) {
   *arr = malloc(...);
}

int main() {
    foo(&arr);
}

En C ++, il est plus simple de modifier foo pour accepter une référence à un pointeur. Le seul changement dont vous avez besoin en C ++ est de changer foo en

void foo(int * & arr)

Puisque vous passez le pointeur par valeur, le pointeur arr dans main ne pointe pas vers la mémoire allouée. Cela signifie deux choses: vous avez vous-même une fuite de mémoire (NON, la mémoire n'est pas libérée une fois la fonction foo terminée), et lorsque vous accédez au pointeur arr à l'intérieur de main, vous accédez à une plage de mémoire arbitraire; pas 3 et donc free () refuse de travailler. Vous avez de la chance que vous n'ayez pas eu une erreur de segmentation en accédant à arr [3] de main.

Vous ne pouvez pas changer la valeur de votre argument (arr) s'il n'est pas passé par référence (& amp;). En règle générale, vous souhaitez renvoyer le pointeur. Votre méthode doit donc être:

arr = foo ();

C’est mauvais juju d’essayer de réaffecter des arguments; Je ne recommande pas la solution (& amp;).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top