Bonjour, cliquez-ici pour vous inscrire et participer au forum.
  • Login:



+ Répondre à la discussion
Page 1 sur 2 1 DernièreDernière
Affichage des résultats 1 à 15 sur 21

c++ declaration d'un int (probleme simple)

  1. cosmoff

    Date d'inscription
    septembre 2012
    Messages
    270

    c++ declaration d'un int (probleme simple)

    Bonjour,

    mon compilateur crie si je met :
    Code:
    int main() 
    {
    int a = 5;
    int a = 5;		
    }
    ce qui me parait logique car la variable 'a' a déja été déclaré, mais si je met :

    Code:
    int main() 
    {
    	while(1)
    	{
    		int a = 5;		
    	}
    }
    alors aucun soucis, pourtant dans la pile il va y avoir plusieurs déclaration d'une meme variable, pourquoi le compilateur ne crie pas ?

    Merci d'avance pour votre aide

    -----

     


    • Publicité



  2. pm42

    Date d'inscription
    juillet 2015
    Messages
    3 653

    Re : c++ declaration d'un int (probleme simple)

    Il n'y a pas plusieurs déclarations d'une même variable mais 1 seule locale à la boucle.
    Tu confonds le code source où il est évident qu'il n'y en a qu'une seule avec l'exécution. Ou là aussi il y en a une seule qui est créée puis détruite à chaque itération.
     

  3. Bluedeep

    Date d'inscription
    décembre 2013
    Localisation
    Isère
    Âge
    56
    Messages
    6 846

    Re : c++ declaration d'un int (probleme simple)

    Bonjour

    Là, il faut revoir la notion de portée des identificateurs.

    http://sdz.tdct.org/sdz/les-identifi...nomsetmasquage
    Dernière modification par Bluedeep ; 11/07/2017 à 08h59.
     

  4. cosmoff

    Date d'inscription
    septembre 2012
    Messages
    270

    Re : c++ declaration d'un int (probleme simple)

    Citation Envoyé par pm42 Voir le message
    Il n'y a pas plusieurs déclarations d'une même variable mais 1 seule locale à la boucle.
    Tu confonds le code source où il est évident qu'il n'y en a qu'une seule avec l'exécution. Ou là aussi il y en a une seule qui est créée puis détruite à chaque itération.
    pour moi la variable 'a' est détuite que lorsque qu'on quitte le boucle (sortie du bloc), et vu que celle ci est une boucle infini alors la variable n'est jamais détruite (car on reste toujours dans le bloc), mais c'est a chaque rebouclage que les variables locales de la boucle sont détruites ?
     

  5. minushabens

    Date d'inscription
    juillet 2014
    Messages
    5 194

    Re : c++ declaration d'un int (probleme simple)

    Il est heureux que les variables soient détruites après chaque itération, autrement on aurait vite fait de remplir la mémoire de l'ordinateur.
     


    • Publicité



  6. jacknicklaus

    Date d'inscription
    janvier 2017
    Messages
    528

    Re : c++ declaration d'un int (probleme simple)

    Citation Envoyé par minushabens Voir le message
    Il est heureux que les variables soient détruites après chaque itération, autrement on aurait vite fait de remplir la mémoire de l'ordinateur.
    Non, pas détruite à chaque itération.
    Détruite en sortie du bloc { }, qui définit sa portée, puisque la variable est ici locale à cette portée.
    Code:
    int main()
    {
        {
            int a = 0;
        }
        {
            int a = 1;
        }
    
        return 0;
    }

    est valide.

    Donc jamais détruite dans le cas d'une boucle infinie comme ici, ou en fin d'itération dans un cas plus réaliste.
    There are more things in heaven and earth, Horatio, Than are dreamt of in your philosophy.
     

  7. Jack

    Date d'inscription
    avril 2003
    Localisation
    Metz
    Messages
    15 957

    Re : c++ declaration d'un int (probleme simple)

    Citation Envoyé par minushabens Voir le message
    Il est heureux que les variables soient détruites après chaque itération, autrement on aurait vite fait de remplir la mémoire de l'ordinateur.
    Les variables ne sont pas détruites après chaque itération, mais lorsque la boucle est terminée.
     

  8. pm42

    Date d'inscription
    juillet 2015
    Messages
    3 653

    Re : c++ declaration d'un int (probleme simple)

    Citation Envoyé par Jack Voir le message
    Les variables ne sont pas détruites après chaque itération, mais lorsque la boucle est terminée.
    Vous êtes sur ? Que se passe t-il si je mets une variable de taille différente à chaque fois :

    Code:
    void foo()
    {
    	for(int i=0; i<10; i++)
    	{
    		char c[i];
    		c[i-1]='A';
    	}
    }
    Ou en C++ une instance de classe avec un constructeur/destructeur ? J'ai l'impression que la variable va bien être détruite à chaque itération.
     

  9. Ikhar84

    Date d'inscription
    octobre 2016
    Localisation
    Avignon
    Âge
    39
    Messages
    246

    Re : c++ declaration d'un int (probleme simple)

    Citation Envoyé par pm42 Voir le message
    Vous êtes sur ? Que se passe t-il si je mets une variable de taille différente à chaque fois :

    Code:
    void foo()
    {
    	for(int i=0; i<10; i++)
    	{
    		char c[i];
    		c[i-1]='A';
    	}
    }
    Ou en C++ une instance de classe avec un constructeur/destructeur ? J'ai l'impression que la variable va bien être détruite à chaque itération.
    Pour moi une nouvelle variable est "créée" sur la pile (stack), puis détruite à la fin du bloc signalé par l'accolade fermante (et donc de la fin de la portée des variable de ce bloc sur la pile)
    Il s'agit donc de variables différentes...

    Pour l'exemple de PM42, ici, on ne travaille pas avec la pile mais le tas (heap) car pointeur (tableau)...
    L'espace mémoire allouée et pointé n'est pas detruit, mais à chaque itération, on réalloue un nouvel espace mémoire sur le tas pour le pointeur: fuite mémoire...

    Quant à l'indice i, je pense qu'à la 2eme itération, i=1, soit pour a[1], on joue un peu avec le feu en allouant pas explicitement (ou réallouant dynamiquement) l'espace mémoire.

    Mais je me trompe sûrement ?
    Cela fais bien longtemps le c/c++ pour moi...
     

  10. pm42

    Date d'inscription
    juillet 2015
    Messages
    3 653

    Re : c++ declaration d'un int (probleme simple)

    Citation Envoyé par Ikhar84 Voir le message
    Pour l'exemple de PM42, ici, on ne travaille pas avec la pile mais le tas (heap) car pointeur (tableau)...
    Non, ce genre de tableau est sur la pile. Dans le doute, prendre le programme, le compiler et lire l'assembleur généré pour s'en convaincre.

    Après, si la variable est de type simple ou de taille fixe, il est effectivement possible d'utiliser le même espace mémoire à chaque itération, c'est même naturel. Mais on peut voir cela comme une optimisation et considéré que sémantiquement, c'est une nouvelle variable à chaque fois.
     

  11. Chanur

    Date d'inscription
    septembre 2011
    Messages
    1 133

    Re : c++ declaration d'un int (probleme simple)

    Citation Envoyé par Ikhar84 Voir le message
    Citation Envoyé par pm42 Voir le message
    Vous êtes sur ? Que se passe t-il si je mets une variable de taille différente à chaque fois :

    Code:
    void foo()
    {
        for(int i=0; i<10; i++)
        {
            char c[i];
            c[i-1]='A';
        }
    }
    Ou en C++ une instance de classe avec un constructeur/destructeur ? J'ai l'impression que la variable va bien être détruite à chaque itération.
    Pour moi une nouvelle variable est "créée" sur la pile (stack), puis détruite à la fin du bloc signalé par l'accolade fermante (et donc de la fin de la portée des variable de ce bloc sur la pile)
    Il s'agit donc de variables différentes...
    C'est ce que je crois aussi. (mais là, j'aurais fait commencer i à 1, parce que char c[0]; c[-1] = 'A'; ça fait carrément froid dans le dos )

    Citation Envoyé par Ikhar84 Voir le message
    Pour l'exemple de PM42, ici, on ne travaille pas avec la pile mais le tas (heap) car pointeur (tableau)...
    L'espace mémoire allouée et pointé n'est pas detruit, mais à chaque itération, on réalloue un nouvel espace mémoire sur le tas pour le pointeur: fuite mémoire...
    Non, c'est bien sur la pile. Et de toute façon on ne détruit pas d'espace mémoire : on déplace le pointeur de la pile. Il n'y pas de fuite mémoire. (voir exemple plus bas)

    Citation Envoyé par Ikhar84 Voir le message
    Quant à l'indice i, je pense qu'à la 2eme itération, i=1, soit pour a[1], on joue un peu avec le feu en allouant pas explicitement (ou réallouant dynamiquement) l'espace mémoire.
    Ben du coup non : c'est parfaitement fiable.

    Citation Envoyé par Ikhar84 Voir le message
    Mais je me trompe sûrement ?
    Effectivement.
    Mais en même temps c'est normal. Moi aussi, il a fallut que je me bricole un exemple pour me clarifier les idées.


    Bon, maintenant l'exemple en question. C'est le même foo, mais un peu plus compliqué : j'ai mis deux tableaux et affiché leur adresse et leur contenu, pour voir où ils sont alloués.
    Code:
    #include <stdio.h>
    int main ()
    {   
        int k; // une première variable pour voir à quoi ressemblent les adresses de la pile
        printf ("k %p\n", &k);
    
    
        for (int i=1; i<20; i++) // la boucle où je crée les tableaux (jusqu'à 20 pour qu'ils changent d'adresse)
        {   
            char c[i]; // premier tableau
            c[i-1]=1;
            printf ("c %p", c); // son adresse
            for (int j=0; j<i; j++)
                printf (" %d", c[j]); // son contenu
            printf ("\n");
    
    
            char d[i]; // deuxième tableau idem
            d[i-1]=2;
            printf ("d %p", d);
            for (int j=0; j<i; j++)
                printf (" %d", d[j]);
            printf ("\n");
        }   
    
    
        return 0;
    }
    ​(et je sais que certains n'aiment pas qu'on utilise printf en C++, mais j'aime bien contrôler le format de ce que j'affiche. Na ! )

    g++ foo.cpp -ofoo
    foo
    [ avec en bleu des commentaires que j'ai ajoutés ]
    Code:
    k 0x7fff06e84110  une première adresse sur la pile
    c 0x7fff06e840d0 1   l'adresse de c, manifestement sur la pile : c'est presque la même que celle de k
    d 0x7fff06e840c0 2   l'adresse de d
    c 0x7fff06e840c0 2 1      deuxième itération : c a changé d'adresse (elle est maintenant à l'ancienne adresse de d)
    d 0x7fff06e840a0 -80 2    d a aussi changé d'adresse
    c 0x7fff06e840c0 2 1 1      troisième itération : les adresses n'ont pas changé (et le contenu de c non plus) : le compilo a prévu de la marge
    d 0x7fff06e840a0 -80 5 2    d n'a pas changé d'adresse mais son contenu a été modifié (par les appels à printf : j'ai vérifié)
    c 0x7fff06e840c0 2 1 1 1       le contenu de c ne change pas
    d 0x7fff06e840a0 -80 5 64 2    le contenu de d est écrasé à chaque fois par les appels à printf
    c 0x7fff06e840c0 2 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 2
    c 0x7fff06e840c0 2 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 0 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 0 0 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 0 0 116 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 0 0 116 28 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 0 0 116 28 -24 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 0 0 116 28 -24 -48 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1 1 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 0 0 116 28 -24 -48 -70 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 0 0 116 28 -24 -48 -70 127 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 0 0 116 28 -24 -48 -70 127 0 2
    c 0x7fff06e840c0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    d 0x7fff06e840a0 -80 5 64 0 0 0 0 0 116 28 -24 -48 -70 127 0 0 2
    c 0x7fff06e840b0 2 64 -24 6 -1 127 0 0 124 7 64 0 0 0 0 0 2 1            il n'y a plus assez de place : on change d'adresse
    d 0x7fff06e84080 -32 8 27 -47 -70 127 0 0 48 65 -24 6 -1 127 0 0 -80 2   idem
    c 0x7fff06e840b0 2 64 -24 6 -1 127 0 0 124 7 64 0 0 0 0 0 2 1 1            pas besoin de changer d'adresse : le compilo a prévu de la marge
    d 0x7fff06e84080 -32 8 27 -47 -70 127 0 0 48 65 -24 6 -1 127 0 0 -80 5 2   etc.
    Maintenant, un exemple avec une classe : c'est beaucoup plus simple à suivre
    Code:
    #include <stdio.h>
    class A
        {
        int attribut;
        public:
        A (int i) { attribut = i; printf ("constructeur %d\n", attribut); };
        ~A () { printf ("destructeur %d\n", attribut); };
        };
    int main ()
        {
        for (int i=0; i<3; i++)
            A a(i);
        return 0;
        }
    Code:
    constructeur 0
    destructeur 0
    constructeur 1
    destructeur 1
    constructeur 2
    destructeur 2
    C'est clair ...
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.
     

  12. minushabens

    Date d'inscription
    juillet 2014
    Messages
    5 194

    Re : c++ declaration d'un int (probleme simple)

    Citation Envoyé par Jack Voir le message
    Les variables ne sont pas détruites après chaque itération, mais lorsque la boucle est terminée.
    comme je ne connais pas c++ je suppose que c'est toi qui as raison. Mais alors ce phénomène est propre à ce langage. Dans le temps je programmais en c (ansi) et j'ai fait tourner des simulations très longues et je pense que sans récupération de la mémoire entre deux itérations ça aurait planté. De mémoire, je pouvais répéter un million de fois un calcul mettant en jeu des matrices 100x100. On est là dans les 10^10 octets.
     

  13. Bluedeep

    Date d'inscription
    décembre 2013
    Localisation
    Isère
    Âge
    56
    Messages
    6 846

    Re : c++ declaration d'un int (probleme simple)

    Citation Envoyé par Jack Voir le message
    Les variables ne sont pas détruites après chaque itération, mais lorsque la boucle est terminée.
    Je n'ai pas touché au C++ depuis .... de longues années mais cette affirmation m'étonne beaucoup : dans ce cas, une boucle avec une variable déclarée dans le bloc d'itération saturerait la pile très vite.
     

  14. Chanur

    Date d'inscription
    septembre 2011
    Messages
    1 133

    Re : c++ declaration d'un int (probleme simple)

    Il n'y a pas de fuite de mémoire : les variables sont déclarées et effacées exactement comme ça se passerait si chaque passage dans la boucle était un appel de fonction.

    En C++, ça marche comme en C, la différence est que la taille d'un tableau peut être variable alors qu'en C elle doit être constante (connue lors de la compilation), et qu'on ne peut déclarer une variable qu'au début d'un bloc (en C++ on peut la déclarer n'importe où).

    Donc on peut toujours faire des boucles qui s’exécutent des milliards de fois, même en déclarant des variables au milieu.

    Il faut juste éviter de le faire en déclarant des objets dont le constructeur ou le destructeur prendrait un temps prohibitif.
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.
     

  15. Tryss2

    Date d'inscription
    août 2015
    Messages
    1 185

    Re : c++ declaration d'un int (probleme simple)

    Citation Envoyé par Chanur Voir le message
    C'est ce que je crois aussi. (mais là, j'aurais fait commencer i à 1, parce que char c[0]; c[-1] = 'A'; ça fait carrément froid dans le dos )
    Tu veux faire des cauchemars?

    Code:
    void foo()
    {
        for(int i=0; 1; i++)
        {
            char a = 'A';
            char c[i];
            c[i-1]=a;
        }
    }



    Ce code ne déclenche généralement pas d'erreur Les joies du C !
     


    • Publicité







Sur le même thème :





 

Discussions similaires

  1. Supprimer un noeud d'un arbre / problème de déclaration
    Par VeryCuriousMan dans le forum Programmation et langages, Algorithmique
    Réponses: 20
    Dernier message: 22/03/2015, 19h16
  2. déclaration en C
    Par philouxy dans le forum Programmation et langages, Algorithmique
    Réponses: 2
    Dernier message: 15/07/2014, 11h04
  3. probleme de declaration des timers et des interruption
    Par elmhamdi dans le forum Électronique
    Réponses: 1
    Dernier message: 07/04/2012, 18h52
  4. programmation C++, problème déclaration de string
    Par loulou40 dans le forum Logiciel - Software - Open Source
    Réponses: 4
    Dernier message: 10/01/2009, 19h34