Partage
  • Partager sur Facebook
  • Partager sur Twitter

ifstream et ouverture de fichier

C++

Sujet résolu
    14 février 2019 à 15:16:10

    Bonjour

    1)

    je souhaite comprendre pourquoi sur MSCV 2017, quand je fais :

    ifstream datas("f.txt");
    	if (!datas.is_open()) {
    		cout << "problème";
    	}

    et que le fichier f.txt est bien incorporé au projet, l'ouverture ne se fait pas et le message "problème" est donc renvoyé.

    le fichier a été inclus au projet, mais il n'est pas situé physiquement dans le répertoire MSVC du projet

    2) Et pourquoi MSVC 2017 est-il beaucoup plus méticuleux et précis que gcc ?

    Merci pour votre aide

    -
    Edité par pseudo-simple 14 février 2019 à 15:46:18

    • Partager sur Facebook
    • Partager sur Twitter
      14 février 2019 à 15:53:06

      1- probablement une histoire de chemin courant actif qui n'est pas celui auquel tu t'attends -- probablement une conséquence que MSVC compile chaque configuration (release, debug) dans des répertoires différents, parfois complètement disjoins des sources. Ajouter un fichier à un projet n'a pas la moindre répercutions pour  l'exécution. Ca ne sert qu'à la chaine de compilation et parfois à des outils tiers. L'exécution se doit être indépendante de toute notion de projet.

      La règle est d'éviter ce que l'on appelle les constantes magiques. Ici, ça serait de recevoir le nom du fichier comme un paramètre de l'application. L'extraire dans les argv/argc. Cela permettra de passer un chemin absolu, ou relatif.

      2- C'est plus compliqué que cela. Ils sont juste tous chatouilleux, mais pas pour les mêmes sujets. Chacun a ses maniaqueries que les autres n'ont pas. Et parfois il y a des bugs, c'est moins vrai de nos jours.

      -
      Edité par lmghs 14 février 2019 à 15:55:21

      • Partager sur Facebook
      • Partager sur Twitter
      C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
        14 février 2019 à 16:07:47

        Merci le problème est maintenant corrigé : je suis allé fouiller manuellement dans les répertoires et j'ai ajouté le fichier manuellement aux répertoires

        Maintenant, le challenge que j'ai est que j'ai un pointeur double qui est bien déclaré et défini.Je le passe en paramètres à la fonction Jacobi de la manière suivante :

        void jacobi(double**A, double*b, double*x0, int &n, double eps) {
        	double s1, s2;
        	// double norm2=norma(b);
        	// double norm=norm2;
        	cout << "Test de n dans Jacobi : " <<n<< endl;
        	cout << "Lecture de A quand on est dans la fonction jacobi" << endl;
        	for (int i = 0; i < n; i++) {
        		for (int j = 0; j < n; j++) {
        			cout << A[i][j] << " ";
        		}
        		cout << endl;

        Or le compilateur MSVC 2017 me dit :

        "Exception levée à 0x00007FF777E4B6AE dans testJacobi.exe : 0xC0000005 : Violation d'accès lors de la lecture de l'emplacement 0xFFFFFFFFFFFFFFFF."

        Ce message ne m'est pas renvoyé par gcc.

        Je voudrais comprendre de quoi ce problème vient.

        Merci pour votre aide

        -
        Edité par pseudo-simple 14 février 2019 à 16:18:58

        • Partager sur Facebook
        • Partager sur Twitter
          14 février 2019 à 16:37:21

          Probablement il n'est pas initialisé. Il y a des options d'analyse de code source dans MSVC. /analyse ou un truc comme ça, je ne sais plus. Cela devrait aider à trouver bon nombre de choses non initialisées.

          -
          Edité par lmghs 14 février 2019 à 16:37:38

          • Partager sur Facebook
          • Partager sur Twitter
          C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
            14 février 2019 à 16:44:55

            >je suis allé fouiller manuellement dans les répertoires et j'ai ajouté le fichier manuellement aux répertoires

            Non, mais, on n'est pas chez mamie, un outil comme un IDE, on prend la peine de lire un minimum sa documentation.

            https://webdevdesigner.com/q/vs2010-how-to-include-files-in-project-to-copy-them-to-build-output-directory-automatically-during-build-or-publish-76307/

            La réponse avec le plus de like, les autres, c'est du bullshit.

            >un pointeur double qui est bien déclaré et défini

            Et l'initialisation, c'est pour quand ? :colere2:

            Avez-vous au moins compris que Visual Studio utilise le concept de "Configuration", et que les projet C++ ont toujours au moins 2 configurations : une "Debug" et une "Release" ?

            Par défaut VS utilise la configuration "Debug" juste après la création du projet.

            Dans une configuration "Debug", customisé pour simplifier le débogage ( captain obvious inside), les variables "non initialisée" sont initialisées avec des valeurs par défaut les plus WTF possible pour détecter rapidement ces conneries de "non initialisation".

            >Je voudrais comprendre de quoi ce problème vient.

            Le problème, il est entre la chaise et le clavier, et Visual Studio vous aide à le localiser.

            (Et utilisez le débogueur de VS pour qu'il vous indique là où ça part en cacahouète)

            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              14 février 2019 à 16:58:34

              Je confirme que je suis bien en mode DEBUG.

              à la compilation , la ligne qui part en cacahouète est bien indiquée et j'ai écrit dans mon message, le message que le debugger m'envoie.

              La question que je me pose, c'est que étant donné que le double pointeur passé en paramètre de Jacobi a une forme particulière de matrice, est-ce que ce n'est pas à cause de cela qu'il y a une erreur qui m'est renvoyé ?

              Car un double pointeur peut prendre différentes formes, et je ne sais pas si la forme du double pointeur que l'on transmet à Jacobi (une matrice) est bien prise en compte quand on fait 

              std::cout<<A[i][j];

              il me semble A est initialisé avec :

              	double**A;
              	double *b;
              	double *x0;
              	int n=3;
              
              	b=new double[3];
              	x0=new double[3];
              	A = new double*[3];
              	for (int i=0;i<n;i++){
              		A[i]=new double[3];
              	}
              
              	lectura(A, b, x0, n);
              	cout << "jacobi" << endl;
              	jacobi(A, b, x0, n, 0.01);



              J'ai modifié la dimension pour assurer l'initialisation. Par contre, mainenant, j'ai des valeurs gigantesques partout quand j'affiche la matrice A au début de la fonction Jacobi.

              -
              Edité par pseudo-simple 14 février 2019 à 18:08:15

              • Partager sur Facebook
              • Partager sur Twitter
                14 février 2019 à 18:47:48

                Bon, primo, vous avez bien changé les réglages de votre fichier "f.txt" à "Toujours copier", ou vous êtes toujours en mode "yolo, mamie m'a dit que je suis le meilleur et les autres c'est que des rageux" ?

                >à la compilation , la ligne qui part en cacahouète est bien indiquée

                Où ça ??? Rien dans vos messages ici, il me semble. (En espérant qu'il nous sorte pas la VA de l'instruction assembleur qui a détecté, par inadvertance, cette GPF (General Protection Fault, ce que veut dire l'erreur 0xC0000005) plus connue sur le vocable francophone de "pointeur merdeux")

                Et PUTAIN, même après plusieurs années, vous confondez toujours erreur de compilation et erreur de runtime, bon dieu de @#%0_°!, ce cours d'OC est vraiment mauvais de chez mauvais et vous l'illustrez à la perfection. :(

                >et j'ai écrit dans mon message, le message que le debugger m'envoie.

                Ok, vous avez bien compris que cela venait du débogueur, alors pourquoi parlez-vous de "compilation", mort bleu !

                Et le message d'erreur du débogueur correspond à ce que j'ai déjà indiqué à mon dernier message : vous faites n'importe quoi avec les pointeurs et Visual Studio a l'amabilité, en configuration Debug, de tout faire pour vous mettre le nez dans votre caca.

                Le testez pas trop, il n'est infaillible. Sur un malentendu, il peut laisser passer des choses et vous serez encore plus dans les embrouilles.

                Utilisez correctement de débogueur, il ne sait pas qu'à afficher des panneaux d'erreur : valeur des variables, pile d'appel, affichage de la mémoire, instruction/ code machine, code source associée, etc... (des centaines de fonctionnalité, sans exagération aucune)

                Mais bon, s'il vous faut le débogueur pour voir les problèmes qui nous hurle aux yeux, à nous pauvres rageux, on n'est très mal barré.

                On n'utilise pas de pointeurs nus, point barre.

                Sinon, on prend la peine de correctement les initialiser, re point barre.

                ET PUIS C'EST TOUT !!!

                >est-ce que ce n'est pas à cause de cela qu'il y a une erreur qui m'est renvoyé ?

                Le débogueur, c'est pas votre psy, il s'en cogne de vos "particularités"', votre programme essaie de lire le contenu de l'adresse "0xFFFFFFFFFFFFFFF" (=-1, comme c'est bizarre, vous avez dit bizarre), qui n'est accessible, sous Windows, qu'à un programme/code en Ring 0 /mode Kernel. Ce que votre code binaire, tout moisi, généré avec Visual Studio en mode "standard" n'est pas, et heureusement pour votre machine (à moins de vraiment beaucoup aimer le bleu).

                C'est donc une illustration des valeurs les plus WTF qu'utilise Visual Studio pour vous aider, INGRAT.

                >Car un double pointeur peut prendre différentes formes,

                Tu l'as dit bouffi !!!

                C'est justement pour cela qu'on ne fait pas ça en C++, car la manière de ranger ces conneries de pointeurs nus est fonction de centaines de paramètre de compilation, du compilateur, voir de la couleur de la robe de la fille du capitaine. Donc, tu maitrises tous ces paramètres et tu fais un truc tout merdique car il ne sera utilisable correctement qu'avec ces mêmes paramètres : GG si ta fonction "jacobi" fait partie de l'API d'une librairie, t'es pas dans la merde.

                Soit tu maitrises pas, et tu te fais pas chier et tu utilises des vrais trucs comme des instances/référence, const pas const, etc... "Keep It Simple and Stupid".

                > et je ne sais pas si la forme du double pointeur que l'on transmet à Jacobi (une matrice) est bien prise en compte

                Et nous non plus, mais on s'en fout, parce que les tambouilles de compilateur, on a passé l'âge.

                EDIT :

                Utilisez le débogueur pour valider vos assertions.

                -
                Edité par bacelar 14 février 2019 à 18:53:26

                • Partager sur Facebook
                • Partager sur Twitter
                Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                  14 février 2019 à 19:58:59

                  Bonsoir OC,

                  j'ai enfin réussi à faire tourner le code sous MSVC <2017 avec la référence sur pointeur après une journée de recherches

                  Une question intéressante m'est venue : 

                  si j'ai une fonction qui prend un paramètre un variable passée par pointeur par exemple

                  int fon(int **p){....};

                  Alors si je considère un pointeur q paramètre passé à fon, j'aimerais savoir si la ressource objet pointée par q, est détruite lorsque l'on sort du scope de la fonction fon ou pas.

                  Pour le pointeur lui-même, je suis sûr que non. Les différents messages d'erreur me font passer que l'objet pointé , lui, est probablement détruit.

                  Merci pour votre aide

                  -
                  Edité par pseudo-simple 14 février 2019 à 20:03:08

                  • Partager sur Facebook
                  • Partager sur Twitter
                    14 février 2019 à 20:16:53

                    C'est l'inverse. Le pointeur est détruit en sortant du scope parce que ce n'est rien de plus qu'une simple variable contenant une adresse.

                    Par contre pour le contenu pointé, si celui-ci a été alloué dynamiquement, bah non il n'est pas détruit. C'est le même problème que tout le monde dénonce depuis le début sur le sujet d'où tu as tiré ton code. Aujourd'hui on a des objets tout fait qui font ça (libérer la mémoire quand le pointeur est détruit) : smart pointers, vector...etc.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 février 2019 à 20:17:06

                      >avec la référence sur pointeur

                      La version informatique du bricolage Chatterton, c'est du solide monsieur !

                      Bon, p et q, c'est pas la même chose, enfin, dans l'alphabet latin du moins, mais bon on va dire que c'est des "synonymes". Dyslexie ?

                      >objet pointée par q, est détruite lorsque l'on sort du scope

                      Bin ça dépend de la couleur de la robe de la fille du capitaine, ou presque.

                      Bin, ça dépend surtout de comment vous avez alloué cet objet, BANANE.

                      Qu'il soit pointé par un pointeur (de mes coui..es) ou pas, ne change rien à l'affaire.

                      Pour un chantre de l'allocation dynamique (new, delete, pointeur nus, etc...), c'est totalement hallucinant de ne même pas savoir la différence avec des variables locales. C'est à la limite du foutage de gueule.

                      >Pour le pointeur lui-même, je suis sûr que non

                      Parce que

                      delete p;
                      p = nullptr;

                      Ça compile pas ? Ça fait pas ce qui est écrit ?

                      Assertion complètement gratuite et complètement fausse, encore une fois.

                      >Les différents messages d'erreur me font passer que l'objet pointé , lui, est probablement détruit.

                      Arrêtez de penser et utilisez le débogueur, BORDEL !!!

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                        14 février 2019 à 20:51:49

                        Maluna34 a écrit:

                        C'est l'inverse. Le pointeur est détruit en sortant du scope parce que ce n'est rien de plus qu'une simple variable contenant une adresse.

                        Par contre pour le contenu pointé, si celui-ci a été alloué dynamiquement, bah non il n'est pas détruit. C'est le même problème que tout le monde dénonce depuis le début sur le sujet d'où tu as tiré ton code. Aujourd'hui on a des objets tout fait qui font ça (libérer la mémoire quand le pointeur est détruit) : smart pointers, vector...etc.


                        Parlez-vous du paramètre p ?

                        Si vous parlez de l'argument q, je ne pense pas qu'il est détruit à la sortie du scope si il n'y pas un delete quelque part

                        -
                        Edité par pseudo-simple 15 février 2019 à 9:35:18

                        • Partager sur Facebook
                        • Partager sur Twitter
                          15 février 2019 à 8:55:31

                          Mais bordel il n'y a pas d'argument q dans ton exemple. xX Vous le sortez d'où.... de votre q ?

                          -
                          Edité par Maluna34 15 février 2019 à 8:59:50

                          • Partager sur Facebook
                          • Partager sur Twitter
                            15 février 2019 à 9:40:16

                            Je répète et précise : si je fais :

                            int fon(int *p){....};

                            et que je passe un argument pointeur q à la fonction f (dont le paramètre est q).


                            Le passage, se fait par pointeur ici.

                            Mais l'objet sous-jacent à q, est-il passé par valeur ou référence ?

                            Et de quel pointeur détruit à la sortie de la fonction fon Maluna parle-t-il ?

                            Merci pour vos explications

                            • Partager sur Facebook
                            • Partager sur Twitter
                              15 février 2019 à 9:45:41

                              Ca dépend de comment est construit le pointeur passé en argument.

                              void foo(int *p)
                              {
                                 // A la fin de foo, p est détruit parce que c'est une variable locale à foo.
                                 // Le contenu pointé (qu'il soit alloué sur la pile ou via new) n'est pas touché
                                 // parce que p est juste une variable qui contient une adresse.
                              }
                              
                              int i {};
                              int *q = &i;
                              foo(&i); // p pointe sur i
                              foo(q); // q est passé par valeur (le pointeur !) donc p pointe sur i
                              foo(new int(0)); // p pointe sur le contenu alloué (fuite mémoire)

                              Si vous avez des lacunes là dessus, revoyez les bases d'un cours C++.

                              -
                              Edité par Maluna34 15 février 2019 à 9:55:35

                              • Partager sur Facebook
                              • Partager sur Twitter
                                15 février 2019 à 11:51:26

                                Merci Maluna34. Ta réponse me permet de rebondir sur un point que j'ai relevé dans le livre de Mr Scott Meyers dans la partie sur les unique_ptr :

                                Il donne le code suivant :

                                auto delInvmt = [](Investment* pInvestment)
                                {
                                makeLogEntry(pInvestment);
                                delete pInvestment;
                                
                                };
                                
                                template<typename... Ts>
                                std::unique_ptr<Investment, decltype(delInvmet)>
                                makeInvestment(Ts&&... params)
                                {
                                std::unique_ptr<Investment, decltype(delInvmt)>
                                pInv(nullptr,delInvmt);
                                
                                
                                ...
                                return pInv;
                                }



                                puisque delInvmt est une fonction (ici lambda) et que la variable paramètre pointeur pInvestment est en principe, détruite à la sortie de la fonction, alors que ici dans cette fonction lambda, il est explicitement indiqué 

                                delete pInvestment;

                                Pourquoi fait-il cela alors ?

                                Merci par avance

                                CREDIT : "Programmez efficacement en C++, de Scott Meyers (Dunod). Copyright 2016 Dunod pour la version française 978-2-10-074391-9, et 2015 Scott Meyers pour la versio d'origine 978-1-491-90399-5"



                                -
                                Edité par pseudo-simple 15 février 2019 à 11:56:55

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  15 février 2019 à 11:57:59

                                  Tu n'as pas compris ce que fait delete.

                                  Il te faut relire un cours de base pour comprendre le concept de delete.

                                  -
                                  Edité par Maluna34 15 février 2019 à 11:58:19

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    15 février 2019 à 12:00:47

                                    "delete p;" libère la mémoire pointée par "p", pas "p" lui-même.

                                    -
                                    Edité par bacelar 15 février 2019 à 12:17:48

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                      15 février 2019 à 12:16:05

                                      Effectivement, je voulais dire "libération de la mémoire.

                                      Donc si je comprends bien, si je fais par exemple :

                                      int f(int *p) {.....}



                                      sans utiliser delete p dans le corps de la fonction, la variable p est détruite à la fin de la fonction, mais la mémoire pointée par p elle n'est pas détruite ?

                                      2) Deuxième question plus importante

                                      Donc cela veut-il dire que si on veut faire un code vraiment propore, il faudrait mettre delete p, dans chaque fonction à laquelle on passe un pointeur p en paramètre pour être sûr d'avoir une libération propre ?

                                      Merci

                                      -
                                      Edité par pseudo-simple 15 février 2019 à 13:54:19

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        15 février 2019 à 14:09:00

                                        @Développeur Dev/ Yes, @YES, man, changes pas de pseudo, sinon, on va être moins conciliant, car on ne saura pas que c'est toi avec tes lacunes "particulières", SVP. (et tu prendras bien plus cher, crois-moi)

                                        >la variable p

                                        Tu nous fait la morale avec la différences entre paramètre et argument ( ton p et ton q des postes précédent) et là, tu nous sort un "variable" bien merdique qui ne veut rien dire de précis, chercher la cohérence.

                                        Ce qui est détruit à la fin de la fonction, c'est les variables locales/automatique créé dans le corps de la fonction et les paramètres empilés dans la stack lors de l'appel de la fonction.

                                        Avec "int*", ce qui est empilé dans la stack, ce n'est qu'un simple nombre représentant une adresse virtuelle en mémoire. En fin de fonction, la libération de ce nombre n'est que son simple "oubli".

                                        p est un nombre, ce qu'il pointe n'est pas forcément un nombre. Ne pas confondre le pointeur et la chose pointée.

                                        >mais la mémoire pointée par p elle n'est pas détruite ?

                                        Pourquoi le serait-elle ? (elle n'est pas détruite, elle est "libérée").

                                        Mais rien n'interdit d'avoir plusieurs pointeurs sur la même zone mémoire, donc rien ne garantit que la zone mémoire pointée par p ne soit pas déjà libérée à la sortie de la fonction (contrairement à des unique_ptr :-° ).

                                        >un code vraiment propore

                                        Avec des pointeurs nus ? Bel oxymore.

                                        > pour être sûr d'avoir une libération propre

                                        Bin non, si vous voulez un puits de données, les "rvalue références" sont tes amies.

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                          15 février 2019 à 14:14:20

                                          Développeur Dev a écrit:

                                          2) Deuxième question plus importante

                                          Donc cela veut-il dire que si on veut faire un code vraiment propore, il faudrait mettre delete p, dans chaque fonction à laquelle on passe un pointeur p en paramètre pour être sûr d'avoir une libération propre ?

                                          NON !! Smart pointers & vector !!

                                          Pas de gestion manuelle de mémoire. Tu lis ce qu'on écrit ou tu te fous de notre gueule ?

                                          Un conseil reprend un cours correct, et qui donc ne parlera PAS de delete ! ;) ;) ;)

                                          https://zestedesavoir.com/tutoriels/822/la-programmation-en-c-moderne/

                                          http://guillaume.belz.free.fr/doku.php?id=programmez_avec_le_langage_c

                                          Salagadou, la menchikabou, la Bibidi Babidi Bou ! :magicien:

                                          Wouah trop facile le C++ !

                                          -
                                          Edité par Maluna34 15 février 2019 à 14:18:53

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            15 février 2019 à 14:28:04

                                            Je reformule en corrigeant les imprécisions, car mon message n'a pas été compris appremment :

                                            Effectivement, je voulais dire "libération de la mémoire".

                                            1) Première question :

                                            Donc si je comprends bien, si je fais par exemple :

                                            int f(int *p) {.....}



                                            sans utiliser delete p dans le corps de la fonction, le pointeur p est détruite à la fin de la fonction, mais la mémoire pointée par p elle n'est pas libérée ?

                                            2) Deuxième question plus importante

                                            Donc cela veut-il dire que si on veut faire un code vraiment propore, il faudrait mettre delete p, dans chaque fonction à laquelle on passe un pointeur p en paramètre pour être sûr d'avoir une libération propre ?

                                            Je pose cette question car je ne comprends pas pourquoi Mr Scott Meyers fait :

                                            auto delInvmt = [](Investment* pInvestment)
                                            {
                                            makeLogEntry(pInvestment);
                                            delete pInvestment;
                                            };

                                            avec justement un delete sur le pointeur en paramètre de la fonction.

                                            C'est la première fois que je vois quelqu'un faire un delete sur un pointeur passé en paramètre d'une fonction.

                                            Merci

                                            -
                                            Edité par pseudo-simple 15 février 2019 à 15:12:24

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              15 février 2019 à 15:22:50

                                              Pour répondre à ta question 2 :

                                              Non.
                                              Que se passerait-il dans le cas suivant ?

                                              int f(int * p)
                                              {
                                                //.....
                                                delete p;
                                              }
                                              
                                              int i;
                                              f(&i);



                                              La fonction du bouquin de Scott Meyers est implémentée pour faire un log avant de libérer la mémoire (via delete), c'est tout.

                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              Si vous ne trouvez plus rien, cherchez autre chose.

                                                15 février 2019 à 15:48:23

                                                L'exemple de code donné par DragonJoker est intéressant. Je l'ai testé sous gcc, le compilateur ne dit rien. Par contre sous MSVC 2017, il s'arrête à l'exécution au niveau du delete, et il semble qu'il y ait pour MSVC 2017 un problème de mémoire.

                                                Et c'est cela que je veux comprendre.

                                                J'ai réarrangé le code de DragonJoker pour m'aider à comprendre ce qu'il se passe de la manière suivante :

                                                #include "pch.h"
                                                #include <iostream>
                                                int f(int * p)
                                                {
                                                	//.....
                                                	std::cout << "test 1 : "<<p << std::endl;
                                                	std::cout << *p << std::endl;
                                                	delete p;
                                                	std::cout << *p << std::endl;
                                                	return 0;
                                                	//std::cout << p << std::endl;
                                                }
                                                int main() {
                                                	int i=1;
                                                	f(&i);
                                                	return 0;
                                                }

                                                Et pour l'instant, je ne comprends pas pourquoi l'exécution s'arrête au niveau du delete.

                                                De plus le code de Mr Scott Meyers, à part le MakeLogEntry manie aussi un delete du pointeur en paramètre de sa fonction

                                                2) Au moment où l'on passe &i à f, est-ce qu'il y a allocation d'une zone mémoire qui est demandée par la fonction f ? 

                                                Comme le passage ne se fait pas par référence, mais par valeur, est-ce que cela veut dire que l'adresse qui est transmise est copiée ?

                                                -
                                                Edité par pseudo-simple 15 février 2019 à 15:54:08

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  15 février 2019 à 16:37:05

                                                  YES, man a écrit:

                                                  et il semble qu'il y ait pour MSVC 2017 un problème de mémoire.

                                                  Non !
                                                  L'implémentation de VS diffère de gcc, il n'ya pas de "problème".

                                                  L'exécution s'arrête car on a affaire à un comportement indéterminé, et chaque compilateur gère cela à sa propre sauce, vu que la norme ne dit rien la dessus.

                                                  Ca plantera chez les uns, et pas chez les autres. C'est le principe même du comportement indéterminé.

                                                  YES, man a écrit:
                                                  Au moment où l'on passe &i à f, est-ce qu'il y a allocation d'une zone mémoire qui est demandée par la fonction f ?

                                                  Est ce que tu voit la moindre instruction effectuant une allocation dynamique ?

                                                  YES, man a écrit:

                                                  Comme le passage ne se fait pas par référence, mais par valeur, est-ce que cela veut dire que l'adresse qui est transmise est copiée ?

                                                  Les valeurs sont forcément copiées avec le passage de paramètre par valeur.

                                                  -
                                                  Edité par Deedolith 15 février 2019 à 16:43:26

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    15 février 2019 à 16:51:48

                                                    Vos questions montrent que vous n'aviez pas le niveau pour comprendre le livre de Scott Meyers.

                                                    Le code de Scott Meyers est une lambda avec un usage extrêmement spécifique, comme l'a indiqué @DragonJoker.

                                                    Cette lambda fait l'assertion que le conteneur utilisant cette lambda à l'ownership sur ses éléments et qu'il n'y a que des éléments alloués dynamiquement dedans. Assertions facile à faire quand on sait se servir correctement des classes et autres smart pointers.

                                                    Mais votre fonction "f" toute moisie est à des années lumières de ce type de conteneur.

                                                    >le compilateur ne dit rien

                                                    Normal, le code est syntaxiquement correcte, et comme vous ne lisez pas les warning et que vous configurez (pas ?) le compilateur comme un pied, il vous laisse faire (c'est toujours vous le chef, malheureusement).

                                                    >Par contre sous MSVC 2017, il s'arrête à l'exécution

                                                    On n'est donc plus à l'exécution, le compilateur vous a aussi laisser faire votre étron.

                                                    C'est juste le débogueur qui vous met le nez dans votre caca.

                                                    Le débogueur a l'amabilité de vous indiquer que vous faites n'importe quoi, car, en configuration Debug, le compilateur c'est arrangé pour maximiser la détection précoce d'erreurs. Mais ici, c'est même plus des erreurs, c'est du foutage de gueule.

                                                    La C-runtime Debug sait si une zone mémoire à bien été allouée par un malloc (le new du C++ appelle le malloc de la C-Runtime en sous-main). Lors de votre "delete" à la manque, la C-Runtime vérifie que ce que vous cherchez à libérer à bien été alloué avant.

                                                    Mais c'est ballot, la variable locale "i" n'a jamais été allouée dynamiquement (dans le tas) via un new ou un malloc, résultat, la C-Runtime vous renvoie dans les cordes pour vous indiquer que vous programmez comme un sagouin.

                                                    Attention, cette vérification n'est pas systématique, la C-Runtime est là pour vous aider, pas pour vous chaperonner.

                                                    >'il y ait pour MSVC 2017 un problème de mémoire

                                                    Non, il vous indique que vous programmez comme un pied.

                                                    Si vous utilisez des pointeurs nus, c'est que l'appelant ne se considère pas comme l'"owner" de l'objet passé en paramètre, il est donc injustifiable que cette fonction fasse la moindre manipulation ayant une action sur l'ownership de l'objet pointé par le pointeur en paramètre. (Sauf cas très particulier des destructeurs et "deleters")

                                                    >je ne comprends pas pourquoi l'exécution s'arrête au niveau du delete.

                                                    Parce que le débogueur est assez gentil pour vous sauver avant de faire encore plus de conneries.

                                                    >De plus le code de Mr Scott Meyers

                                                    Est un "deleter", c'est un cas très très particulier de fonction.

                                                    >est-ce qu'il y a allocation d'une zone mémoire

                                                    Cette zone mémoire n'est pas allouée dans la tas, via new/malloc, mais dans la stack, comme les variables locales/automatiques des fonctions appelantes et appelées.

                                                    >est-ce que cela veut dire que l'adresse qui est transmise est copiée ?

                                                    Oui, sous la forme de un entier (ou plusieurs en fonction du type pointé) dans la stack.

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                                      15 février 2019 à 17:40:47

                                                      J'ai continué les tests qui bloquaient pour mieux comprendre, voici ce que j'ai fait  (mes questions viennent après) :

                                                      #include "pch.h"
                                                      #include <iostream>
                                                      int f(int * p)
                                                      {
                                                      	
                                                      	std::cout << "test 1 : "<<p << std::endl;
                                                      	std::cout << *p << std::endl;
                                                      	delete p;
                                                      	
                                                      	return 0;
                                                      	
                                                      }
                                                      int main() {
                                                      	int i=1;
                                                      	int *k = new int(1);
                                                      	f(k);
                                                      	int *j = &i;
                                                      	f(j);
                                                      	f(new int(1));
                                                      	f(&i);
                                                      	return 0;
                                                      }

                                                      Trois questions :

                                                      1) le cas de la variable j que j'ai déclaré dans ce morceau de code, est-il une allocation statique (étant donné que ce n'est pas une allocation dynamique) ?

                                                      2) Si on suppose donc que l'objet x que l'on passe à f a bien été alloué dynamiquement, est-que le pointeur p est automatiquement désalloué en sortie de fonction (comme le serait une variable statique classique)  ou bien il faut le faire manuellement avec delete avant la sortie de la fonction f pour être sûr que la mémoire est bien libérée ? (d'où l'idée des smarts pointers...)

                                                      3) Dans ce cas, est-ce que on a un risque de fuite mémoire ? C'est-à-dire que devient la ressource objet qui était associée dans p au sein de la fonction f ?

                                                      Merci pour vos explications

                                                      -
                                                      Edité par pseudo-simple 15 février 2019 à 17:42:27

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        15 février 2019 à 18:18:47

                                                        1)

                                                        >est-il une allocation statique

                                                        Non, c'est ni statique ni dynamique, c'est une variable automatique, donc dans la stack.

                                                        2)

                                                        >(comme le serait une variable statique classique)

                                                        C'est pas des variables statiques, c'est des variable locale/automatique.

                                                        delete ne désalloue pas le pointeur, mais la chose pointée, BORDEL !!!

                                                        La désallocation des variables locales et des paramètres passés par copie n'utilise pas delete.

                                                        delete c'est pour les variables dans le tas, les variables locales et les paramètre passés par copie sont dans la stack. Les mécanismes d'allocation et de désallocation sur la stack n'a rien à voir avec de l'allocation dynamique (sur le tas).

                                                        >ou bien il faut le faire manuellement avec delete

                                                        Tu cherches vraiment à ce que le débogueur te mette le nez dans ton caca ???

                                                        >avant la sortie de la fonction f pour être sûr que la mémoire est bien libérée ?

                                                        Pour être sure de faire de la merde, surement.

                                                        >(d'où l'idée des smarts pointers...)

                                                        Lis ce putain de cours sur le C++ moderne, BORDEL.

                                                        3)

                                                        >Dans ce cas, est-ce que on a un risque de fuite mémoire ?

                                                        Si ce n'était que ça, c'est vraiment le moindre des problèmes.

                                                        >C'est-à-dire que devient la ressource objet qui était associée dans p au sein de la fonction f ?

                                                        Rien de spécial, et c'est tant mieux. Un passage par pointeur nu implique que la fonction n'a pas à toucher à cette ressource, POINT BARRE.

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                                          15 février 2019 à 18:41:15

                                                          bacelar, croyez-moi que j'ai bien étudié plusieurs cours, et que voss réponses expliquées avec vos mots me permettent de comprendre des choses que je viens seulement de comprendre et qui ne sont écrites que dans très peu de cours.

                                                          Par exemple, grâce à vous j'ai découvert aujourd'hui l'allocation automatique.

                                                          Et vous m'avez permis avec DragonJoker et les autres de mieux comprendre ce qu'il se passe avec le delete, et le passage par pointeur aussi, qui sont des sujets sur lesquels beaucoup font l'impasse.

                                                          Par conséquent, cela m'aide à mieux comprendre ce que vous entendez par désallocation de la ressource pointée. Ainsi dans le code Scott Meyers, en faisant cette lambda fonction , il libère la ressource pointéé par pInvestment sur le tas ?

                                                          auto delInvmt = [](Investment* pInvestment)
                                                          {
                                                          makeLogEntry(pInvestment);
                                                          delete pInvestment;
                                                          
                                                          };
                                                          
                                                          template<typename... Ts>
                                                          std::unique_ptr<Investment, decltype(delInvmet)>
                                                          makeInvestment(Ts&&... params)
                                                          {
                                                          std::unique_ptr<Investment, decltype(delInvmt)>
                                                          pInv(nullptr,delInvmt);
                                                          
                                                          
                                                          ...
                                                          return pInv;
                                                          }



                                                          -
                                                          Edité par pseudo-simple 17 février 2019 à 14:14:09

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            15 février 2019 à 19:40:16

                                                            Non, il ne libère pas les ressources "pointée", comme par magie.

                                                            il fournit une spécialisation du template std::unique_ptr pour la classe Investment.

                                                            Et dans cette spécialisation, il fournit un "deleter" par défaut différent du "deleter" du cas général du template std::unique_ptr.

                                                            Ce "deleter" sera appelé quand l'implémentation du template std::unique_ptr estimera qu'elle doit libérer la ressource qu'il est le seul à pointer (par définition de l'usage "valide" de ce template). Un std::unique_ptr à toujours l'ownership de ce qu'il pointe.

                                                            Cette libération peut aussi bien se faire dans le destructeur du std::unique_ptr quand le code sort du bloc l'ayant déclaré/alloué en variable locale que dans un opérateur d'affectation et tout autre fonction de la classe qui doit libérer la ressource.

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                                              15 février 2019 à 23:35:08

                                                              J'ai encore deux questions sur unique_ptr car je veux les comprendre en profondeur alors que je suis actuellement focalisé sur les smarts pointers justement :

                                                              Première question :

                                                              Supposons que l'on a un smart pointeur p, disons un unique_ptr p par exemple.

                                                              en principe la la libération de la mémoire liée à la ressource empactée est, rendue automatique (elle contient en fait un new en interne)

                                                              Lors de la destruction automatique de p :

                                                              Est-ce que c'est d'abord la ressource vers laquelle p pointe qui est libérée en finde scope? puis elle est détruite automatiquement en fin de scope ? 

                                                              Sinon quelles sont les étapes précises de la libération ou destruction de la valeur smart pointer p en détails ?

                                                              Deuxième question :

                                                              le deleter proposé par Mr Scott Meyers est-il présenté juste parce que l'on a ajouté la fonction MakeLogEntry et que ainsi, ça permet de personnaliser le deleter alors que le comportement par défaut est juste le delete que j'ai indiqué précédemment dans la lambda fonction ?

                                                              Merci à vous tous

                                                              -
                                                              Edité par pseudo-simple 16 février 2019 à 0:04:21

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              ifstream et ouverture de fichier

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown