Partage
  • Partager sur Facebook
  • Partager sur Twitter

Comparaison between ptr and integer

Sujet résolu
    31 juillet 2021 à 23:15:07

    Bonjour.

    J'ai un code qui fait :

    		while(*(ptrInt+sizeof(int)*x) != NULL){
    			printf("%d\n", *(ptrInt+sizeof(int)*x));
    			x++;
    		}

    Mon ide me donne un avertissement : comparison between pointer and integer.

    Je pense pourtant que le code est valide. Comment faire ce code sans avertissement ?

    Contexte :

    /*
     ============================================================================
     Name        : ProgrammingProblem-3-21.c
     Author      : 
     Version     :
     Copyright   : Your copyright notice
     Description : 
     ============================================================================
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/mman.h>
    
    #include <sys/shm.h>
    #include <unistd.h>
    
    int collatzConjecture(int n, int* ptrInt){
    	if(n%2 == 0){
    		n = n/2;
    	}else{
    		n = 3*n+1;
    	}
    
    	if(n != 1){
    		*ptrInt = n;
    		collatzConjecture(n, ptrInt+sizeof(int));
    	}else{
    		*ptrInt = n;
    	}
    
    	return n;
    }
    
    int main(int argc, char* argv[]) {
    	const char* name = "OS";
    	const int SIZE = sizeof(int)*20;
    
    	if(argc != 2){
    		printf("%s\n", "Usage : <int n>");
    		return 0;
    	}
    
    	int fd;
    	fd = shm_open(name ,O_CREAT | O_RDWR , 0666);
    	ftruncate(fd, SIZE);
    	int* ptrInt = (int *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    
    	pid_t pid = fork();
    
    	if(pid==0){ // child
    
    		int n = atoi(argv[1]);
    
    		collatzConjecture(n, ptrInt);
    
    	}else{
    		wait(NULL);
    		int x = 0;
    		while(*(ptrInt+sizeof(int)*x) != NULL){
    			printf("%d\n", *(ptrInt+sizeof(int)*x));
    			x++;
    		}
    
    		shm_unlink(name);
    	}
    
    
    	return EXIT_SUCCESS;
    }
    



    -
    Edité par Adrien Supra 31 juillet 2021 à 23:17:56

    • Partager sur Facebook
    • Partager sur Twitter
      31 juillet 2021 à 23:53:02

      Tu compares un entier avec NULL.

      la valeur NULL s'utilise pour un pointeur pas pour un entier.

      • Partager sur Facebook
      • Partager sur Twitter
        1 août 2021 à 0:01:10

        Bonsoir,

        Le type de l'expression *(ptrInt+sizeof(int)*x) est int. Le type de l'expression NULL est un type pointeur. Comparer ces deux expressions est le problème signalé par le compilateur.

        Je vois plusieurs problèmes. D'abord, puisque ptrInt est de type pointeur de int, il n'y a guère de sens à ajouter un décalage multiplié par sizeof(int). Ensuite, la notation *(pointeur + décalage) est peu lisible, on préfère pointeur[décalage]. Enfin, puisque l'on a un tableau de int, on s'attend éventuellement à y trouver 0, pas NULL.

        En conclusion, while (ptrInt[x] != 0) est plus correct, pour autant que le reste du code est aussi correct (je n'ai pas tout vérifié, je te laisse voir).

        • Partager sur Facebook
        • Partager sur Twitter
          1 août 2021 à 0:43:25

          Hello,

          Comme l'indique Marc Mongenet, pas besoin de multiplier le décalage par sizeof(int). Cela s'applique également ligne 32: pas ptrInt+sizeof(int), mais bien ptrInt+1

          -
          Edité par edgarjacobs 1 août 2021 à 0:43:54

          • Partager sur Facebook
          • Partager sur Twitter

          Il y a ceux qui font des sauvegardes, et ceux qui n'ont pas encore eu d'incident....

            1 août 2021 à 3:09:23

            Hello.

            Vous avez bien raison ici @MarcMongenet & @edgarjacobs :

            ptrInt[x]
            ptrInt+x

            Mais... l'output pour ptrInt[x] != NULL n'est pas le même que l'output pour *(ptrInt+sizeof(int)*x) != NULL
            Il ne s'agit donc pas d'un équivalent parfait.

            Du coup vous n'avez pas raison ici @MarcMongenet :

            != 0

            Voir avec le code l'output :

            while(ptrInt[x] != 0)

            Et

            while(ptrInt[x] != NULL)

            Output :

            106
            (et c'est tout)

            Et avec :

            while(ptrInt[x] != 1)

            Output :

            106
            53
            160
            80
            40
            20
            10
            5
            16
            8
            4
            2
            1 <--- le con ne s'arrete pas !! -_-'
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0
            0

            et avec mon code :

            while(*(ptrInt+sizeof(int)*x) != NULL)

            Output (l'attendu... "le correct") :

            106
            53
            160
            80
            40
            20
            10
            5
            16
            8
            4
            2
            1
            (fin parfait...)

            Il est possible que mon code soit le bon mais qu'il ne corresponde pas a une utilisation habituel ou "classique" du langage ce qui expliquerai que mon IDE le relève. Un avertissement a ne pas prendre en compte ?

            -
            Edité par Adrien Supra 1 août 2021 à 3:28:28

            • Partager sur Facebook
            • Partager sur Twitter
              1 août 2021 à 3:24:15

              t#Étrange, tu testes si c'est différent de un et tu affiches un avant la série de zéros.
              Est-ce que tu affiches ce que tu testes?
              Où veux-tu vraiment arrêter? Peut-être qu'il faut changer le test:
              while(ptrInt[x] >= 1)
              • Partager sur Facebook
              • Partager sur Twitter

              Le Tout est souvent plus grand que la somme de ses parties.

                1 août 2021 à 3:52:48

                Dans l'absolue je veux arréter aux valeurs non initialisé... (mon code fonctionne, je me demandais juste en quoi il n'était pas conventionnel, puisqu'il sort un avertissement)

                Dans les fait après la valeur 1.

                A première vu aucun test sous la forme ptrInt[x] n'est concluant.

                Et d'ailleurs les forme ptrInt[x] ne donne pas les même ouput que les formes ptrInt+x

                Exemple :

                while(ptrInt[x] > 0)

                Output :

                106
                (fin)

                while(ptrInt+x> 0)

                Output :

                106
                53
                160
                80
                40
                20
                10
                5
                16
                8
                4
                2
                1
                0
                0
                0
                0
                0
                0
                0
                0
                0
                0
                0
                [dizaine et dizaine de 0]
                0
                0
                0
                0
                0
                4
                5
                6
                1879048176
                1879047925
                0
                0
                0
                -650901390
                -1111064162
                -364957480
                (fin)

                -
                Edité par Adrien Supra 1 août 2021 à 4:00:48

                • Partager sur Facebook
                • Partager sur Twitter
                  1 août 2021 à 4:23:09

                  ptrInt+x n'est pas une valeur mais l'adresse de cette valeur.
                  Essaies  *(ptrInt+x)
                  Et tester par rapport à ce qui "n'a pas été initialisé" n'est pas une bonne idée.
                  Même si la plupart du temps, le système place 0 dans les positions non initialisées, il ne faut pas s'y fier.
                  Si tu as bien la valeur  1  dans le tableau, tu es censé la trouver.
                  Et je te repose la question, est-ce que tu affiches ce que tu testes?
                  while(*(ptrInt+x) > 0) {
                   printf("%d\n", *(ptrInt+x));
                  }
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Le Tout est souvent plus grand que la somme de ses parties.

                    1 août 2021 à 9:25:08

                    bonjour

                    houla ! on fait pause et on respire !

                    En C, si p est un pointeur et n un entier alors en octets : p+n = adresse de p + (n fois la taille de ce qui est pointé par p en octets). C'est de l'arithmétique de pointeur de base ! Il va falloir revoir ces notions.

                    De plus la notation p[n] est un sucre syntaxique pour *(p+n) ; ce qui signifie aussi que l'on peut tout aussi bien écrire n[p] pour avoir le même résultat.

                     Ensuite je ne comprends pas pourquoi tu fais inutilement compliqué dans ton code. Il te faut une fonction qui te calcule le suivant de la séquence, une autre qui l'utilise et remplit la zone de mémoire partagée … et qui vérifie s'il n'y a pas d'overflow !

                    • Partager sur Facebook
                    • Partager sur Twitter
                      1 août 2021 à 11:54:46

                      Lol... sa te remet trop de notion en cause, c'est toi qui halètes :p

                      Test le code avec p+n p[n] et *(p+sizeof(int)*n) il n'y a aucune correlation dans l'output entre les 3.

                      Après je ne sais pas pour quoi je fais si compliqué... Qu'est-ce qui te parait compliqué ? Je test la mémoire partagé POSIX. Simplifie le code montre moi. La consigne de l'exercice c'est le processus1 calcul la série et processus2 imprime la série, utiliser la mémoire partager norme POSIX pour transmettre les informations du processus1 au processus2.

                      -
                      Edité par Adrien Supra 1 août 2021 à 11:56:55

                      • Partager sur Facebook
                      • Partager sur Twitter
                        1 août 2021 à 12:56:13

                        si p est un pointeur sur int,

                        p+n est un pointeur

                        p[n] est le nième int après p --- s'écrit aussi *(p+n)

                        *(p+sizeof(int)*n) est le nn*sizeof(int) ième int après p

                        Normal que les trois outputs donnent des résultats différents.

                        -
                        Edité par edgarjacobs 1 août 2021 à 13:00:51

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Il y a ceux qui font des sauvegardes, et ceux qui n'ont pas encore eu d'incident....

                          1 août 2021 à 18:11:23

                          Je te suggère de lire atentivement ce qui suit sur l'arithmétique des pointeurs:
                          http://public.iutenligne.net/informatique/algorithme-et-programmation/priou/LangageC/132_arithmtique_des_pointeurs.html
                          Tu as réservé avec mmap() l'espafce pour 20 entiers (int) partagé entre le processus père et le fils.
                          C'est le fils qui écrit dans l'espace et le père qui le lit. Jusqu'ici, pas de problème.
                          D'abord, tu as choisi le nombre 106, ce qui donne une séquence de 13 nombres se terminant par 1.
                          Si tu avais choisi un autre nombre, la séquence aurait pu dépasser 20 entiers.
                          Tu aurais écrit en dehors de la zone réservée et tu aurais détruit qquelque chose.
                          Comme on ne sait pas quoi, le comportement du programme est imprévisible, c'est ce qu'on appelle indéterminé.
                          Quand tu écris  ptrInt+sizeof(int), tu n'avances pas de 4 adresses, mais de 4 entiers, donc 16 adresses.
                          Dans l'exemple, tu as 13 nombres, mais ils sont répartis sur 52 positions, donc en dehors de la zone réservée.
                          Tu étais cohérent dans ton erreur, c'est pourquoi tu as cru que les nombres étaient consécutifs.
                                  collatzConjecture(n, ptrInt+sizeof(int));
                          Ici, tu veux avancer à la case suivante, mais tu avances de 4 cases, ce qui t'amènera rapidement trop loin. Il faut écrire:
                                  collatzConjecture(n, ptrInt+1);
                          Tu dois faire le même genre de correction partout dans ton code.
                          Tu pourrais définir un symbole avec #define pour donner le nombre d'entiers à réserver. Et ce nombre pourait être nettement plus grand que 20 sans problème.

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Le Tout est souvent plus grand que la somme de ses parties.

                            2 août 2021 à 0:03:20

                            Ok @PierrotLeFou. Tout ce que tu as dit est très claire.

                            Le programme fonctionne a présent avec la syntaxe ptrInt[x] et collatzConjecture(n, ptrInt+1);

                            Merci beaucoup pour cette correction. Désolé aux autres de ne pas avoir pensé a remettre en cause mon appel récursif ou de vous avoir mal lu.

                            -
                            Edité par Adrien Supra 2 août 2021 à 0:11:57

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Comparaison between ptr and integer

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            • Editeur
                            • Markdown