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 :

Return tableau d'entiers


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de mailbox
    Profil pro
    Inscrit en
    Février 2010
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2010
    Messages : 140
    Par défaut Return tableau d'entiers
    Bonjour,

    j'ai une fonction saisie, dans laquelle je remplie un tableau d'entiers (ce sont des arguments passés en ligne de commande et convertis en entiers) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int saisie (int argc, char *argv[])
    {
        int tableau[MAX];
    ...
    ...
         return *tableau;
    }
    Le tableau s'affiche correctement dans la fonction, mais j'essaye de l'afficher dans mon main, et là ca ne marche plus...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main (int argc, char *argv[])
    {
        int i, tableau[MAX];
     
        saisie(argc, argv);
     
        for (i=1; i< MAX-2; i++)
            printf("%d\n", tableau[i]);
     
        return 0;
    }

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    C'est parceque ton tableau est une variable locale de ta fonction (et donc construit sur la pile).

    Dès que tu quittes la fonction, la pile est restaurée et le tableau est invalidé (je ne dit pas détruit mais il devient n'importe quoi).

    plusieurs manières pour corriger ton problème :
    1. C'est l'appelant qui fournit le tableau
    2. L'appelé alloue un tableau (par malloc() sur le tas) et ne crée plus un tableau sur la pile. L'appelant ne doit pas oublier de libérer ce tableau.
    3. Le tableau dans l'appelé est un tableau static (et donc dans un autre segment mémoire). C'est probablement le plus rapide mais tu perds la réentrance et le multi thread (voir code ci dessous).


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int saisie (int argc, char *argv[])
    {
    static     int tableau[MAX];
    ...
    ...
         return *tableau;
    }
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre confirmé Avatar de mailbox
    Profil pro
    Inscrit en
    Février 2010
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2010
    Messages : 140
    Par défaut
    * Mon appel de la fonction serait alors :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    saisie(argc, argv, tableau); ?
    * Tableau sur la pile?

    * Je ne vois pas bien de quoi tu parles quand tu dis :
    réentrance et multi thread

    ^^

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par mailbox Voir le message
    * Mon appel de la fonction serait alors :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    saisie(argc, argv, tableau); ?
    * Tableau sur la pile?
    Pour le cas 1 (je viens de modifier ma réponse initiale pour numéroter les cas), oui, pour le cas 2 ou 3, il n'y a pas de changement dans l'appel

    Citation Envoyé par mailbox Voir le message
    * Je ne vois pas bien de quoi tu parles quand tu dis :
    réentrance et multi thread
    C'est que ce n'est probablement pas ton problème mais j'essaye d'expliquer.

    Si ta variable est static (comme dans le code que je t'ai donné), c'est la même variable (la même adresse mémoire) qui sera utilisé si 2 thread (ou plus) utilisent la même fonction. Ca c'est pour le multi thread.

    C'est presque le même problème pour la réentrance.

    Imagine une fonction factorielle qui soit codée de manière réentrante avec une variable statique (exemple un peu idiot ci dessous)
    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
     
    int fact(int nb)
    {
    static int level = 0;
       int res = 0;
       if(nb == 1)
       {
          res = 1;
       }
       else
       {
          level++;
          res = nb * fact(nb -1);
       }
       printf("level=%d\n", level);
       return res;
    }
    la même variable static level (même adresse mémoire) serait toujours incrémentée par les différents niveaux de récursion ce qui fait que l'on aurait une valeur completement farfelue pour le niveau de réentrance.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre confirmé Avatar de mailbox
    Profil pro
    Inscrit en
    Février 2010
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2010
    Messages : 140
    Par défaut
    J'ai fait la solution 1. et ca marche Merci!

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    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 833
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par mailbox Voir le message
    * Je ne vois pas bien de quoi tu parles quand tu dis : réentrance et multi thread
    La réentrance c'est un soucis majeur du programmeur quand il veut mémoriser une info seulement dans une fonction.
    La solution de base est de passer par une variable static. Ainsi sa valeur perdure et peut être réutilisée quand on revient dans la fonction.

    Mais le problème se pose si on entre deux fois dans la fonction à l'occasion de deux activités distinctes.
    Exemple: compteur d'appels
    Code c : 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
    void fct(int valeur)
    {
         static int cpt=0;
     
         cpt+=1;
         printf("j'ai reçu %d %d fois\n", valeur, cpt);
    }
     
    int main()
    {
        for (i=0; i < n; i++)
       {
             // J'appelle la fonction pour i
             fct(i);
     
             for (j=0; j < m; j++)
             {
                  // J'appelle la fonction pour j
                  fct(j);
             }
        }
    }

    L'idée de l'algo c'est que i et j étant indépendantes, une fois que la boucle j sera épuisée, i passe à 1 et fct(i) soit lui-aussi indépendant. Mais comme la variable interne "cpt" est unique pour tout le programme, elle a été corrompue par les appels fct(j). Et quand fct(i) est appelé une seconde fois, cpt n'est pas à 2 comme on le voudrait.

    La solution est de ne pas passer par de statiques et d'apporter à la fonction la variable devant stocker l'info.

    Le multithread découle de ce problème. A l'origine, la programmation parallèle ne passait que par fork(). Le fork() étant indépendant, le processus fils créé possède une copie de la mémoire du père. Et toute modif de la mémoire par le fils ne modifie que la copie et ne corromp pas la zone mémoire du père.
    Le multithread, arrivé bien après mais issu du monde zindow, est aussi un outil de programmation parallèle... sauf que lui ne dissocie pas la mémoire pour les processus. Tous les threads (processus parallèles) tapent dans la même zone mémoire. Et cet effet démultiplie le problème de la réentrance....
    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]

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

Discussions similaires

  1. Charger un fichier dans tableau d'entier
    Par nico0007 dans le forum Langage
    Réponses: 12
    Dernier message: 17/04/2008, 11h30
  2. Limite Allocation Mémoire d'un tableau d'entier
    Par l9ft b9hind dans le forum C++
    Réponses: 5
    Dernier message: 27/10/2005, 19h29
  3. convertir tableau d'entier en char[]
    Par nin47 dans le forum C
    Réponses: 20
    Dernier message: 12/10/2005, 20h03
  4. Réponses: 2
    Dernier message: 03/10/2005, 22h16
  5. Réponses: 6
    Dernier message: 23/05/2005, 10h47

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