7
votes

Erreur lors du passage du pointeur au tableau des structures

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

struct Point {
    double x;
};

void test(struct Point **a, int len)
{
    int i;

    printf("a = %p\n", a);
    for (i = 0; i < len; ++i)
        printf("%f\n", a[i]->x);
}

int main()
{
    int i;
    int len = 4;

    struct Point *P;

    P = malloc(len*sizeof(struct Point));

    for (i = 0; i < len; ++i) {
        P[i].x = i;
        printf("%f\n", P[i].x);
    }
    printf("&P = %p\n", &P);
    test(&P, len);

    return 0;
}
I am trying to pass an array of structs to a function (I want to pass a pointer to the array, not make a copy). When I try to use the array inside the function, I get an access violation. What is the correct way to do this? What am I doing wrong? a == &P, so it should work, right?

2 commentaires

Mais p déjà est un pointeur, il pointe du premier élément de la mémoire allouée (la matrice). En passant le pointeur, vous ne remplissez rien que le pointeur réel.


printf ("% f \ n", (* a) [i] .x);


5 Réponses :


3
votes

Passer & p à fonctionner Test signifie que vous passez un pointeur sur le premier élément d'un tableau de un élément de type Point de structure * . Par conséquent, seul A [0] est valide (et donc a [0] -> x ) et tous les autres a [i] sont sortis d'accès lié. Cela invoquera un comportement non défini.

Changer A [i] -> x à a [0] [i] .x ou (* a) [i] .x dans Test fonction.

Utiliser le pointeur sur le pointeur dans ce cas n'est pas digne. Cela vaut la peine d'utiliser si le pointeur passé doit être modifié dans la fonction et que la modification devrait être vue dans l'appelant.


9 commentaires

ou meilleur (* a) [i] .x


@Wojciechfrohmberg, n'est-il pas censé être ce que Joachimpileborg a suggéré dans le commentaire ci-dessus?


@Coolguy si nous avons struct point ** a (* a) est la déséroférence d'un pointeur [i] lit la valeur de l'adresse Donc, fondamentalement, la déréférence du pointeur ... Cela signifie après ces deux opérations, nous obtenons un type struct point ERGO: Nous ne pouvons pas accéder comme nous obtiendrons struct point * ...


@Wojciechfrohmberg, je pense que vous avez raison. Alors, le commentaire de Joachim est faux alors qu'il ne déprivent que le pointeur de trois fois?


@Un gars sympa; Oui. Je pense qu'il était confus alors comme moi.


@ Hacks, et comme moi :). @ Joachimpileborg, c'est faux. Voir les commentaires ci-dessus.


@ Joachimpileborg; Je pense que maintenant vous serez désaccord sur la modification de A [i] -> x à (* a) [i] -> x .


a [i] sera faux quand même. Alors, que diriez-vous de (* a) [i] .x ? :)


@ Joachimpileborg; Ouais. (* a) [i] .x est bien quand même.



5
votes

Pourquoi vous voulez-vous un struct point ** ? Vous pouvez réécrire la même chose que xxx

et l'appeler comme xxx

de cette façon, IMHO, l'exigence

je veux transmettre un pointeur sur le tableau

est également rempli # .


(#) Remarque: Pour être strict, nous passons ici le pointeur Le premier élément du tableau Cependant, le comportement se compare égal. Merci à M. @alk pour le commentaire.


5 commentaires

Merci, donc juste pour vous assurer, aucune copie n'est faite lorsqu'elle est dans la fonction, et les modifications que je fais au tableau persistent toujours après la déclaration de fonction?


À Nitpick: la façon dont vous montrez un pointeur sur un élément de 1er élément de tableau est passé. Ceci est différent d'un pointeur à un tableau, ce dernier serait Struct Point (* Pa) [len] .


@alk très vrai monsieur. Pouvez-vous suggérer les formulations appropriées pour modifier ma réponse?


Bien qu'il n'y ait aucun avantage d'utiliser struct point ** , le seul code de code OP est A [i] -> x .


@Haccks droit monsieur. IMHO, OP est très préoccupé par ne pas effectuer une partie de copie plutôt que le type de données lui-même. Donc, j'ai juste essayé de le mettre de manière simplifiée. :-)



1
votes

Le tableau doit être transmis à l'aide du paramètre struct point * A code>. Lorsque vous incrémentez a code> le pointeur se déplacera par Tailleof (Point de structure) code>.

void test(const struct Point *a, int len)
{
    ...
}


0 commentaires

1
votes

D'autres réponses vous offrent de meilleures alternatives. Mais je vais mettre cela ici pour aider quiconque (moi-même) comprendre pourquoi il est faux.

Entrez la description de l'image ici


0 commentaires

0
votes

Je veux transmettre un pointeur sur le tableau,

Prendre votre exigence littéralement vous le faites comme ceci: xxx

et appelez-le comme ceci: xxx

vous pourrait également mettre en œuvre la même fonctionnalité (en boucle sur les éléments de la matrice) en faisant la voie proposée par Sourav Ghosh 's Réponse . Vous passerez ensuite un pointeur sur l'élément de la matrice 1 st puis, mais un pointeur sur le tableau lui-même.


0 commentaires