Partage
  • Partager sur Facebook
  • Partager sur Twitter

Allouer dynamiquement un tableau d'int

    11 juillet 2018 à 11:35:06

    Bonjour,

    J'essayer de faire une fonction qui renvoie un tableau d'int compris entre mes parametres min et max. Le code me semble correct mais j'obtiens toujours soit une seg fault, soit une suite de chiffres comme 46474800 (en fonction des compilateurs).

    Quelqu'un pourrait-il m'aider ?

    #include <stdlib.h>
    
    int		*ft_range(int min, int max);
    
    int		*ft_range(int min, int max)
    {
    	int				*tab;
    	unsigned int	buffer;
    
    	buffer = 0; // Important
    	if (min >= max)
    		return (NULL);
    	tab = (int *)malloc((max - (min + 1)) * sizeof(int));
    	while (buffer <= (max - (min + 1)))
    	{
    		tab[buffer] = min + buffer;
    		buffer++;
    	}
    	return (tab);
    }
    
    int		main(int argc, char **argv)
    {
    	ft_range(*argv[0], *argv[1]);
    	return (0);
    }
    ./a.out 1 9
    4647480%
    ./a.out 0 5
    [1]    81873 segmentation fault  ./a.out 0 5




    • Partager sur Facebook
    • Partager sur Twitter
      11 juillet 2018 à 11:49:41

      Salut :

      pour min = 0 et max = 5

      taille = max - (min +1)  = 5 - (0+1) = 4

      La vraie formule est max - min +1, ou sans ambiguité : (max - min) +1 

      Sinon, remplace ton while de la ligne 14 par un for. Il n'est pas pertinent de mettre un while quand on itere sur une variable (comme ici "buffer")

      -
      Edité par Fvirtman 11 juillet 2018 à 11:50:50

      • Partager sur Facebook
      • Partager sur Twitter

      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

        11 juillet 2018 à 12:05:58

        Concernant la taille de mon tableau, merci.

        Par contre le problème persiste...

        Et j'utilise un while a la place d'un for par obligation.

        • Partager sur Facebook
        • Partager sur Twitter
          11 juillet 2018 à 13:21:51

          ThomasFlt a écrit:

          Par contre le problème persiste...

          Et j'utilise un while a la place d'un for par obligation.

          Nous le savons, mais c'est désagréable à lire. D'ailleurs je me dis que c'est peut-être un plan machiavélique pour décourager le copier-coller: obliger à écrire si moche qu'il est extrêmement peu probable que les élèves trouvent du code à copier-coller sans devoir adapter toutes les boucles.

          A part ça, l'appel ft_range(*argv[0], *argv[1]); est très bizarre. Sais-tu ce que valent *argv[0] et *argv[1]?

          Et je ne vois pas d'affichage dans le code.

          -
          Edité par Marc Mongenet 11 juillet 2018 à 13:22:16

          • Partager sur Facebook
          • Partager sur Twitter
            11 juillet 2018 à 14:29:22

            Marc Mongenet a écrit:

            ThomasFlt a écrit:

            Par contre le problème persiste...

            Et j'utilise un while a la place d'un for par obligation.

            Nous le savons, mais c'est désagréable à lire. D'ailleurs je me dis que c'est peut-être un plan machiavélique pour décourager le copier-coller: obliger à écrire si moche qu'il est extrêmement peu probable que les élèves trouvent du code à copier-coller sans devoir adapter toutes les boucles.

            Un argument intéressant. Cependant, d'une année sur l'autre, ils peuvent récupérer les travaux qu'on fait les autres membres de leur secte l'année précédente. A moins qu'ils gardent tout pour eux ? 

            • Partager sur Facebook
            • Partager sur Twitter

            Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

              11 juillet 2018 à 14:36:49

              argv[0] et argv[1] sont les paramètres du main, ils sont passés après la compilation. Dans mon cas ils valaient 1 et 9 (./a.out 1 9)

              Ah et j'ai enlevé l'affichage avant de poster mais il est habituellement présent.

              • Partager sur Facebook
              • Partager sur Twitter
                11 juillet 2018 à 14:45:00

                Oui ils valent 1et 9 dans ton cas. Cependant ce sont des chaines de caracteres qui contiennent et 1 et 9 et non directement des entiers.
                • Partager sur Facebook
                • Partager sur Twitter
                  11 juillet 2018 à 14:48:55

                  ThomasFlt a écrit:

                  argv[0] et argv[1] sont les paramètres du main, ils sont passés après la compilation. Dans mon cas ils valaient 1 et 9 (./a.out 1 9)

                  Moi j'aurais dit que *argv[0] vaut '.', et *argv[1] vaut '1'. Mais bon, si tu as testé...

                  • Partager sur Facebook
                  • Partager sur Twitter
                    11 juillet 2018 à 14:58:45

                    Marc Mongenet a écrit:

                    ThomasFlt a écrit:

                    argv[0] et argv[1] sont les paramètres du main, ils sont passés après la compilation. Dans mon cas ils valaient 1 et 9 (./a.out 1 9)

                    Moi j'aurais dit que *argv[0] vaut '.', et *argv[1] vaut '1'. Mais bon, si tu as testé...


                    J'apprends le code Marc, J'APPRENDS. Mais bon, si tu savais pas...

                    Sinon mon code ressemble a ça maintenant (j'ai rajouté une fonction atoi pour convertir les arguments en int et laissé l'affichage)

                    #include <stdlib.h>
                    #include <stdio.h>
                    
                    int		ft_atoi(char *str);
                    int		*ft_range(int min, int max);
                    
                    int		ft_atoi(char *str)
                    {
                    	int	i;
                    	int	temp;
                    	int	neg;
                    
                    	i = 0;
                    	temp = 0;
                    	neg = 1;
                    	while (str[i] == 32 || (str[i] >= 0 && str[i] <= 32))
                    		i++;
                    	if (str[i] == 45 && str[i + 1] > 45)
                    	{
                    		neg = -1;
                    		i++;
                    	}
                    	if (str[i] == 43)
                    		i++;
                    	while (str[i] >= 48 && str[i] <= 57)
                    	{
                    		temp = temp * 10 + str[i] - 48;
                    		i++;
                    	}
                    	return (neg * temp);
                    }
                    
                    int		*ft_range(int min, int max)
                    {
                    	int				*tab;
                    	unsigned int	buffer;
                    
                    	buffer = 0; // Important
                    	if (min >= max)
                    		return (NULL);
                    	tab = (int *)malloc(((max - min) + 1) * sizeof(int));
                    	while (buffer <= max - min + 1)
                    	{
                    		tab[buffer] = min + (buffer + 1);
                    		buffer++;
                    	}
                    	// **** Affichage ****
                    	for (int i = 0; i <= buffer; i++)
                    		printf("%d", tab[i]);
                    	// *******************
                    	return (tab);
                    }
                    
                    int		main(int argc, char **argv)
                    {
                    	ft_range(ft_atoi(argv[1]), ft_atoi(argv[2]));
                    	return (0);
                    }

                    -
                    Edité par ThomasFlt 11 juillet 2018 à 15:16:26

                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 juillet 2018 à 16:49:26

                      Hello,

                      Je digresse, mais cette méthode d'apprentissage est vraiment débile.

                      Voilà un bonhomme à qui on demande d'écrire une fonction qui alloue un tableau de int en fonction de deux valeurs, à qui ça pose un problème, et le voilà obligé d'écrire sa propre fonction atoi qui est potentiellement génératrice de problèmes, tout ça car la librairie standard lui est interdite (tient, malloc est autorisé ?) :euh:

                      C'est comme si pour allumer mon barbecue, j'employais des silex plutôt que des allumettes.

                      -
                      Edité par edgarjacobs 11 juillet 2018 à 16:58:34

                      • Partager sur Facebook
                      • Partager sur Twitter

                      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                        16 juillet 2018 à 8:01:02

                        problème corrigé :

                        #include <stdlib.h>
                        #include <stdio.h>
                        
                        int	 ft_atoi(char *str);
                        int	 *ft_range(int min, int max);
                        
                        int	 ft_atoi(char *str)
                        {
                        	int i;
                        	int temp;
                        	int neg;
                        
                        	i = 0;
                        	temp = 0;
                        	neg = 1;
                        	while (str[i] == 32 || (str[i] >= 0 && str[i] <= 32))
                        	{
                        		i++;
                        	}
                        	if ( str[i] == 45 && str[i + 1] > 45 )
                        	{
                        		neg = -1;
                        		i++;
                        	}
                        	if ( str[i] == 43 )
                        	{
                        		i++;
                        	}
                        	while (str[i] >= 48 && str[i] <= 57)
                        	{
                        		temp = temp * 10 + str[i] - 48;
                        		i++;
                        	}
                        	return (neg * temp);
                        }
                        
                        int	 *ft_range(int min, int max)
                        {
                        	int *tab;
                        	unsigned int buffer;
                        
                        	buffer = 0; // Important
                        	if (min >= max)
                        	{
                        		return (NULL);
                        	}
                        
                        	tab = (int *)malloc(((max - min) + 1) * sizeof(int));
                        	if ( !tab )
                        	{
                        		return ( NULL );
                        	}
                        
                        
                        	while ( buffer < ( max - min + 1 ) )
                        	{
                        		tab[buffer] = min + buffer;
                        		buffer++;
                        	}
                        	// **** Affichage ****
                        	for (int i = 0; i < buffer; i++)
                        	{
                        		printf("%d\n", tab[i]);
                        	}
                        	// *******************
                        	return (tab);
                        }
                        
                        int	 main(int argc, char **argv)
                        {
                        	int *tab = ft_range( ft_atoi( argv[1] ), ft_atoi( argv[2] ) );
                        
                        	free ( tab );
                        	return (0);
                        }

                        ligne 42 tu débordais de la zone alloué pour ton tableau :

                        buffer <= max - min + 1 
                        // avec :
                        // max = 2
                        // min = 1
                        buffer = 0 //ok
                        buffer = 1 //ok
                        buffer = 2 //ok
                        buffer = 3 //ko

                        ligne 48 tu affiche encore plus que de raison :

                        i < buffer
                        i = 0 //ok
                        i = 1 //ok
                        i = 2 //ok
                        i = 3 //ok
                        i = 4 //ko
                        

                        et tu ne voyais pas le truc car dans l'affichage tu n'avais pas mis de "\n" à la ligne 49.

                        de plus tu avais une fuite mémoire car tu ne faisais pas le free ().



                        -
                        Edité par ox223252 16 juillet 2018 à 8:02:19

                        • Partager sur Facebook
                        • Partager sur Twitter

                        la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

                        Mon GitHub

                          16 juillet 2018 à 15:43:39

                          Tout est plus clair maintenant. Un grand merci !
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Allouer dynamiquement un tableau d'int

                          × 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