IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

renvoyer l'adresse d'un seul objet d'un tableau de structure


Sujet :

C

  1. #1
    Membre actif Avatar de BioKore
    Homme Profil pro
    Dresseur d'Alpaga
    Inscrit en
    Septembre 2016
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Dresseur d'Alpaga

    Informations forums :
    Inscription : Septembre 2016
    Messages : 300
    Points : 219
    Points
    219
    Par défaut renvoyer l'adresse d'un seul objet d'un tableau de structure
    Bonjour à tous,

    Je bute depuis peu sur un ou deux problèmes qui je pense sont tout bête et certainement liés, mais mon code prenant de l'ampleur, je préfère demander votre avis avant de refondre en partie ce dernier.

    Je souhaiterais faire passer à une fonction l'adresse d'une unique case d'un tableau.
    En effet, j'ai un tableau d'objet (du type struct str *obj), et ma fonction doit traiter dans un ordre défini chaque case du tableau. ci dessous, un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    struct network {
    	int net_nb_int;		// size of input vector
    	int net_nb_out;		// size of output vector
    	int net_nb_lay;		// size of layer vector
     
    	double *net_int;	// input vector
    	double *net_out;	// output vector
     
    	layer_t *net_layer;	// layer vector
    };
     
    struct layer {
    	int layer_nb_int;	// size of layer input vector
    	int layer_nb_ker;	// size of kernel vector
     
    	double *layer_int;	// layer input vector
    	double *layer_out;	// layer output vector
     
    	kernel_t *layer_ker;	// kernel vector
    };
     
    typedef struct network net_t;
    typedef struct layer layer_t;
     
     
     
    double* fst_func(net_t *net, double *u_entries)
    {
    	net->net_out = snd_func(net->net_layer[0], u_entries);
     
    	for (int l = 1; l < net->net_nb_lay; l++)
    	{
    		net->net_out = snd_func(net->net_layer[l], net->net_out);
    	}
     
    	return net->net_out;
    }
     
     
    double* snd_func(layer_t *lay, double *u_ent)
    {
    	for (int k = 0; k < lay->layer_nb_ker; k++)
    	{
    		lay->layer_out = thrd_func(lay->layer_ker, u_ent);
    	}
     
    	return lay->layer_out;
     
    }
    Or, dans la première fonction, je ne peux pas faire : net->net_out = snd_func(net->net_layer[0], u_entries); car la seconde fonction attends une adresse comme premier paramètre. Mais je ne peux pas m'amuser à lui envoyer tout le tableau simplement car je ne veux traiter que l'objet net_layer[0] et pas tout le tableau net_layer. Dans la fonction suivante, j'ai un truc du genre net_layer[0].var[i] = xxx;

    Alors, je sais bien évidemment que je peux tourner mon code différemment mais modifier dans le fond toute cette partie me fait reprendre pas mal de code en amont et en aval ; je voudrais doc éviter de passer à coter de quelque chose comme par exemple envoyer : &(net->net_layer[0]). mais ceci me génère aussi une erreur de segmentation.

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Pour avoir l'adresse du premier élément d'un tableau, il suffit d'utiliser &(net->net_layer[0]) comme tu l'as fait, et comme le nom d'un tableau correspond à l'adresse du premier élément, net->net_layer marcherait aussi. Ton code plante certainement car ton net_layer n'est peut être pas un tableau, il faudrait voir le code qui met à jour net avant d'appeler fst_func().
    Et ne t'inquiète pas de transmettre un tableau entier car cela est impossible en C, de la même manière que l'on ne peut pas copier un tableau en utilisant un égal entre deux tableaux.

  3. #3
    Membre actif Avatar de BioKore
    Homme Profil pro
    Dresseur d'Alpaga
    Inscrit en
    Septembre 2016
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Dresseur d'Alpaga

    Informations forums :
    Inscription : Septembre 2016
    Messages : 300
    Points : 219
    Points
    219
    Par défaut merci
    Super, merci pour ce retour. Effectivement, je me suis aperçu entre temps que j'avais certains bugs aussi dans l'initialisation ; j'ai été un peu trop rapide sur certains points.

    Cependant, pendant que j'y penses, pourquoi ne peut-on pas renvoyer de tableaux vers un tableau. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    double* ma_fonction()
    {
        double tab[20] = {0.0};
        return tab;
    }
     
    double unTab[50];
    unTab = ma_fonction();    // ne fonctionne pas
     
    // mais : 
     
    double *un_tab;
    un_tab = malloc(sizeof(double)*50);
     
    un_tab = ma_fonction(); // ceci fonctionne
    Pourquoi ? je viens de m'en rendre compte tout à l'heure et... Je trouve ça déroutant.

  4. #4
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Et non, ça ne fonctionne pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    double* ma_fonction() {
        double tab[20] = {0.0};
        return tab;
        // le compilateur doit émettre ici un warning signalant l'anomalie
        // on retourne l'adresse du premier élément du tableau qui est
        // l'adresse de quelque chose qui disparaît dès la fonction terminée.
    }
     
    double unTab[50];
    unTab = ma_fonction();    // ne fonctionne pas
    // erreur de compilation, on ne peut pas copier un pointeur dans un tableau
     
    // mais : 
    double *un_tab;
    un_tab = malloc(sizeof(double)*50);
     
    un_tab = ma_fonction(); // ceci semble fonctionner!
    // compile car le compilateur voit une copie de pointeur dans un pointeur
    // mais résultat désastreux, la zone réservée par le malloc est perdue,
    // le pointeur pointe désormais sur une zone non valide (adresse de qqch de disparu!)

  5. #5
    Membre actif Avatar de BioKore
    Homme Profil pro
    Dresseur d'Alpaga
    Inscrit en
    Septembre 2016
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Dresseur d'Alpaga

    Informations forums :
    Inscription : Septembre 2016
    Messages : 300
    Points : 219
    Points
    219
    Par défaut
    Ah.... J'ai toujours fait comme ça

    Donc on est obligés de passer le tableau à modifier en paramètre de la fonction ?? Il n'y a donc aucune utilité à retourner des pointeurs à une fonction ?


    Comment puis-je récupérer mes valeurs sans envoyer un tableau supplémentaire en paramètre (oui, je préfère avoir des fonctions avec le moins de paramètres possible, c'est plus propre et compréhensible) ??

    Merci.

  6. #6
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Citation Envoyé par BioKore Voir le message
    Donc on est obligés de passer le tableau à modifier en paramètre de la fonction ??
    Oui
    Citation Envoyé par BioKore Voir le message
    Il n'y a donc aucune utilité à retourner des pointeurs à une fonction ?
    Quand une fonction retourne un pointeur, il doit pointer sur quelque chose, et ça ne peut pas être l'adresse d'une locale ou un tableau.
    Ça peut être de la mémoire allouée, ou l'adresse de quelque chose qui existait avant la fonction, ou l'adresse d'une statique.
    Citation Envoyé par BioKore Voir le message
    Comment puis-je récupérer mes valeurs sans envoyer un tableau supplémentaire en paramètre (oui, je préfère avoir des fonctions avec le moins de paramètres possible, c'est plus propre et compréhensible) ??
    S'il y a plusieurs choses à retourner, on passe en paramètre les adresses de données à mettre à jour, ou l'adresse d'une structure s'il y en a beaucoup. Il est aussi possible que la fonction retourne une structure (on peut tout retourner sauf un tableau), c'est très rarement utilisé mais possible
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    struct PourRetour {
       int  a;
       char str[5+1];  // la structure peut contenir des tableaux!
    };
    struct PourRetour fct( int x ) {
       struct PourRetour  st;
     
       st.a = x;      // on remplit la structure résultat
       strcpy( st.str , "hello" );
     
       return st;     // retour d'une structure
    }
    int main() {
       struct PourRetour  z;
     
       z = fct( 2 );       // La structure retournée est copiée dans z
       printf("Il y a un tableau '%s' qui a été copié car il est dans une structure\n" , z.str );
    }

  7. #7
    Membre actif Avatar de BioKore
    Homme Profil pro
    Dresseur d'Alpaga
    Inscrit en
    Septembre 2016
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Dresseur d'Alpaga

    Informations forums :
    Inscription : Septembre 2016
    Messages : 300
    Points : 219
    Points
    219
    Par défaut
    Ok, merci bien pour ces retours...


    Justement, j'ai commencé à retaper le code pour retourner la structure complète plutôt que la partie tableau de la structure.

    Je vais néanmoins devoir refondre mon code mais bon... C'est un autre problème..

    Merci pour ces éléments ; je devrais m'en sortir maintenant ; j'ouvrirais un post plus spécifique à mon projet si j'ai encore des soucis de ce genre.

  8. #8
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Attention, il est plus optimal de passer l'adresse de la structure à la fonction, sinon il y aura une recopie.

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par BioKore Voir le message
    Citation Envoyé par dalfab Voir le message
    Attention, il est plus optimal de passer l'adresse de la structure à la fonction, sinon il y aura une recopie.
    Bonjour
    Petite précision sur la phrase de dalfab: quoi qu'on fasse, il y a toujours recopie quand on passe quelque chose à une fonction. C'est d'ailleurs la raison qui fait qu'une fonction ne peut pas modifier la variable qu'elle reçoit car elle n'a pas vraiment reçu une variable, mais seulement une copie de sa valeur. Mais il vaut mieux recopier l'adresse d'une structure (une adresse fait 4 ou 8 octets) que la structure elle-même (qui peut faire plusieurs dizaines/centaines d'octets)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Membre actif Avatar de BioKore
    Homme Profil pro
    Dresseur d'Alpaga
    Inscrit en
    Septembre 2016
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Dresseur d'Alpaga

    Informations forums :
    Inscription : Septembre 2016
    Messages : 300
    Points : 219
    Points
    219
    Par défaut
    Merci pour ces infos ! Je suis finalement repassé au mode : &(obj->tab[i]);J'ai refondu une partie de mon code en tentant de simplifier au maximum ; je n'ai plus le problème initial, mais malgré tout, je continue à galérer sur un sujet plus ou moins similaire (voir mon post suivant).

    Merci à vous.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Un état pour un seul objet
    Par spekal dans le forum UML
    Réponses: 1
    Dernier message: 20/06/2006, 09h53
  2. Ouvrir une adresse dans une seule fenêtre
    Par efficks dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 01/04/2006, 10h45
  3. Modifier la couleur d'un seul objet d'une ListBox
    Par [Silk] dans le forum Composants VCL
    Réponses: 8
    Dernier message: 03/01/2006, 21h55
  4. 2 compositions pour un seul objet
    Par Jorus dans le forum Diagrammes de Classes
    Réponses: 6
    Dernier message: 31/10/2005, 13h41
  5. Réponses: 13
    Dernier message: 25/01/2005, 10h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo