IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Problème allocation mémoire


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Par défaut Problème allocation mémoire
    Bonjour, j'ai un souci d'allocation mais je ne sais pas du tout comment y remédier, en fait, je liste le contenu du dossier path, je sépare les dossier des fichiers ( j'ai enlevé l'étape des fichiers pour alléger le code). En fait, lorsque je veux lister le contenu du /home ( il y a 990 dossiers ), j'ai un peu du n'importe quoi qui s'affiche a l'ecran, bref, manque de place. Si je liste le contenu de mon dossier personnel en revanche, je n'ai aucun souci. Comment savoir combien de place je dois allouer ?

    Au passage, si vous avez des critiques/ remarques sur mon code, elles sont les bienvenues

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    int listerDossier(char *path, Fichier *list_fichier)
    {
    	// Declaration
    	const char *regex="^\\.[[:alnum:]]+"; // Expression permettant de supprimer les fichiers caches
    	DIR *dir;
    	Fichier *dossiers;
    	int d_i;
    	int i,j;
    	int nb_fichier= 0;
    	regex_t preg;
    	struct dirent *ptrent;
    	struct stat st;
     
    	// Allocation
    	dossiers= (Fichier *)malloc(NB_FICHIER_MAX*BUFFER*sizeof(Fichier));
     
    	// Ouverture du dossier
    	if(stat(path, &st) == 0)
    	{
    		if(S_ISDIR(st.st_mode))
    		{// Evite le favicon.ico
    			if((dir= opendir(path)) == NULL)
    			{
    				perror("Dossier inexistant ou non autorise en lecture\n");
    				exit(errno);
    			}
    			d_i= 0;
    			while((ptrent= readdir(dir)) != NULL)
    			{
    				// Prend le chemin absolu du fichier
    				char abs[254];
    				sprintf(abs, "%s%s", path, ptrent->d_name);
     
    				if((stat(abs, &st)) < 0)
    				{
    					perror("Erreur de stat\n");
    					exit(errno);
    				}
    				if((regcomp(&preg, regex, REG_EXTENDED | REG_NOSUB)) == 0)
    				{// Compilation de la regex
    					if((regexec(&preg,ptrent->d_name,0,NULL,0)) != 0)
    					{// Execution de la regex
    						regfree(&preg);
    						if((strcmp(ptrent->d_name, "..")) == 0)
    						{// Repertoire parent en tete de liste
    							list_fichier[0].nom= ptrent->d_name;
    							list_fichier[0].type= 'p';
    						}
    						else if((strcmp(ptrent->d_name, ".")) == 0)
    						{ /* On enleve le repertoire courant */ }
    						else if(S_ISDIR(st.st_mode))
    						{
    							dossiers[d_i].nom= ptrent->d_name;
    							dossiers[d_i].type= 'd';
    							dossiers[d_i].taille= st.st_size;
    							dossiers[d_i].modif= st.st_mtime;
    							d_i++;
    							nb_fichier++;
    						}
    					}
    				}
    			}
    			closedir(dir);
    		}
    	}
    	printf("Nombre d'elements: %d \nNombre de dossiers: %d\n", nb_fichier, d_i);
     
    	// Triage des dossiers et fichiers par ordre alphabetique
    	qsort(dossiers, (size_t) d_i, sizeof(dossiers[0]), compare);
     
    	// Rajout des dossiers et fichiers dans le pointeur final
    	for(i=1, j=0; i <= d_i; i++, j++)
    	{
    		list_fichier[i].nom= dossiers[j].nom;
    		list_fichier[i].type= dossiers[j].type;
    		list_fichier[i].modif= dossiers[j].modif;
    	}
    	// Liberation de l'espace memoire
    	free(dossiers);
     
    	return nb_fichier;
    }
    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Pour que ton code soit valable quelque soit le nombre de fichiers, il faut que tu fasses de l'allocation dynamique à chaque nouveau fichier ajouté (liste chainée).

    Même chose pour ce type de déclaration: char abs[254]; Il faudrait en toute logique, que tu alloues de la place pour abs en fonction des longueurs de path et de ptrent->d_name.

    Mais surtout, ce type d'affectation: dossiers[d_i].nom= ptrent->d_name; est erroné. Tu ne donnes pas la description de la structure Fichiers mais je suppose que nom est un pointeur.
    Il faudrait allouer de la place pour dossiers[d_i].nom (=malloc(strlen(ptrent->d_name)+1); et recopier ptrent->d_name dedans via strcpy.

  3. #3
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Par défaut
    Merci pour ce début de réponse

    J'ai une dernière question, comment modifier mon code pour faire de l'allocation dynamique justement? Je vois pas trop comment faire et c'est surtout la dessus que je bloque

    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Tu modifies ta structure Fichier comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct
    {
        ....
        Fichier *next;
    } Fichier;
    Pour gérer ta liste chaînée, tu vas avoir besoin au minimum d'un pointeur vers le premier élément de la liste.

    Ensuite, à chaque nouveau fichier traité, il faut que tu alloues une nouvelle structure:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dossiers = (Fichier *)malloc(sizeof(Fichier));
    Après avoir renseigné la structure pointée par dossiers, il faut l'insérer dans ta liste.

    On pourrait faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dossiers->next = first;
    first = dossiers;
    Mais il se trouve que tu veux trier les fichiers par ordre alphabétique. Les zones mémoires allouées par malloc n'étant pas obligatoirement contigües, tu ne vas pas pouvoir utiliser qsort comme tu l'as fait dans ton code. Le mieux est donc de trier directement lors de l'insertion en développant une fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    insertion(dossiers,(Fichier **) &first);
    Pour l'implémentation de la fonction d'insertion, je me contente d'un "bête" parcours séquentiel; A adapter en fonction de tes besoins de tri:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void insertion(Fichier *dossiers,Fichier **first)
    {
        Fichier *cour, *prec;
     
        for (cour=first,prec=0;(cour != 0) && (strcmp(cour->nom,dossiers->nom)<0);cour=cour->next)
        {
            prec = cour;
        }
        dossiers->next = cour;
        if (prec != 0)  prec->next = dossiers;
        else *first = dossiers;
     
    }
    Enfin, la fonction de libération, à appeler en fin de traitement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    libere(&first);
       ...
    void libere(Fichier **first)
    {
        Fichier *cour,*next;
     
        for (cour=*first;cour != 0;)
        {
          next = cour->next;
          free(cour);
          cour = next;
        }
        *first = 0;  // la raison pour laquelle je passe un **
    }

  5. #5
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Par défaut
    Bon, je t'avouerai que j'ai pas tout compris...
    Au passage, ma structure Fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct
    {
        char *nom;
        char type;
        off_t taille;
        time_t modif;
    } Fichier;
    Citation Envoyé par josse95
    Tu modifies ta structure Fichier comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct
    {
        ....
        Fichier *next;
    } Fichier;
    Pour gérer ta liste chaînée, tu vas avoir besoin au minimum d'un pointeur vers le premier élément de la liste.

    Le premier élément de la liste, c'est pas *dossiers[0] justement ?
    Citation Envoyé par josse95
    Ensuite, à chaque nouveau fichier traité, il faut que tu alloues une nouvelle structure:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dossiers = (Fichier *)malloc(sizeof(Fichier));
    Je devrais ça ou dans mon code?

    Citation Envoyé par josse95
    Mais il se trouve que tu veux trier les fichiers par ordre alphabétique. Les zones mémoires allouées par malloc n'étant pas obligatoirement contigües, tu ne vas pas pouvoir utiliser qsort comme tu l'as fait dans ton code. Le mieux est donc de trier directement lors de l'insertion en développant une fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    insertion(dossiers,(Fichier **) &first);
    J'ai pas compris a quoi servirai ta fonction insertion, au passage, avant t'as dis que first était un pointeur (*) et maintenant un tableau de pointeurs (**), c'est possible ?

    pour les réponses , mais je t'avouerai que c'est bien compliqué pour moi tout ça
    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Bon ne mélangeons pas tout.....

    Tu étais parti sur un tableau, tu peux rester sur un tableau...


    Tu peux démarrer comme tu le faisais, sauf que je ne sais pas pourquoi il y avait BUFFER :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	dossiers= (Fichier *)malloc(NB_FICHIER_MAX*sizeof(Fichier));

    Ensuite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	// Prend le chemin absolu du fichier
    	char *abs=NULL;
     
    	abs = malloc ( (strlen(path)+strlen(ptrent->d_name)+1) ;
    	if ( abs == NULL )
    	   {
    	       fprintf ( stderr, "Erreur allocation mémoire\n");
    	       continue ;
    	   }
    	sprintf(abs, "%s%s", path, ptrent->d_name);
    Ne pas oublier le free à la fin...

    Ensuite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	if((strcmp(ptrent->d_name, "..")) == 0)
    	   {// Repertoire parent en tete de liste
    		list_fichier[0].nom= strdup(ptrent->d_name);
    		list_fichier[0].type= 'p';
      	   }
    Et tu as oublié je crois d'incrémenter nombre_fichiers pour ce cas...


    Et ensuite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	else if(S_ISDIR(st.st_mode))
    	   {
    	        dossiers[d_i].nom= strdup(ptrent->d_name);
    Et enfin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	// Rajout des dossiers et fichiers dans le pointeur final
    	for(i=1, j=0; i <= d_i; i++, j++)
    	{
    		list_fichier[i].nom= strdup(dossiers[j].nom);
    Et tu n'incrémentes pas le nombre de fichiers...


    ET FINALEMENT, pour vérifier si tu ne dépasses pas ta capacité max :

    au moment où tu fais :

    tu devrais tester par rapport à ton nombre max, et réallouer une plus grand place si besoin est :

    Au début de la routine tu places :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Fichier temp = NULL ;
    int      N_Max = NB_FICHIER_MAX ;
    Et ensuite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    	nb_fichier++;
     
    	if ( nb_fichiers == N_MAX )
    	  {
    	       temp = (Fichier *)realloc(fichiers, 
    				 (N_MAX+NB_FICHIER_MAX)*sizeof(Fichier));
    	       if ( temp != NULL )
    	         {
    	            N_MAX = N_MAX + NB_FICHIER_MAX ;
    	            fichiers = temp ;
    	            temp = NULL ;
    	         }
    	       else
    	         {
    	            nb_fichiers = 0 ;
    	            fprintf ( stderr, "Erreur allocation mémoire\n");
    	            break ;
    	         }
    	 }

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par josse95
    Pour que ton code soit valable quelque soit le nombre de fichiers, il faut que tu fasses de l'allocation dynamique à chaque nouveau fichier ajouté (liste chainée).


    ça n'a absolument rien à voir avec l'allocation dynamique......

    Tu pourrais prendre ce que 'ai donné ci-dessus et le faire à chaque nouveau fichier.. Ce que j'ai donné est juste pour ne pas avoir à le faire à chaque fichier, mais on peut le faire à chaque fichier sans inconvénient....

    C'est une question de conception, de savoir si on prend une liste chaînée ou un tableau.. sans plus..

  8. #8
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Par défaut
    Un grand merci à tous ( et à toi souviron )



    Les strdup ont suffit, j'ai juste changer deux ou trois choses, j'avais déjà modifié l'allocation pour abs
    Bref tout fonctionne, seule chose que j'avais pas compris, c'est que j'allouais trop de place!

    Tout roule comme sur des roulettes maintenant, merci

    Bon week-end de Pâques
    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    souviron34 a écrit:
    ça n'a absolument rien à voir avec l'allocation dynamique......
    Ah ouais, elle est bien bonne celle là !

    Et comment appelles tu le fait de faire des malloc ?


    Effectivement, il pouvait rester sur un tableau. Mais tant qu'à utiliser des pointeurs, autant apprendre à réaliser une liste chaînée. Enfin, bon, tu as fait ton petit numéro, tu dois être content.

  10. #10
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par josse95
    Ah ouais, elle est bien bonne celle là !
    .
    Si en plus tu sais pas lire......

    Je parlais des listes chaînées par rapport aux tableaux...

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

Discussions similaires

  1. Problème allocation mémoire
    Par Nico28 dans le forum Windows Forms
    Réponses: 0
    Dernier message: 16/07/2010, 14h04
  2. Problème allocation mémoire
    Par Keewee dans le forum C++
    Réponses: 17
    Dernier message: 14/03/2008, 13h33
  3. Problème allocation mémoire
    Par Hurin dans le forum Débuter
    Réponses: 7
    Dernier message: 04/02/2008, 23h03
  4. Problème allocation mémoire - malloc () 1Gb
    Par Gellius31 dans le forum Bibliothèque standard
    Réponses: 14
    Dernier message: 21/12/2007, 12h16
  5. problème allocation mémoire
    Par kinta dans le forum C++
    Réponses: 7
    Dernier message: 09/02/2006, 23h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo