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 d'allocation de tableau


Sujet :

C

  1. #21
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par siempre Voir le message
    Bonsoir,

    Quelle est la différence entre free(t) et free(t[i]) ?
    t est un pointeur de type char ** alloué à un certain moment
    t[i] est un pointeur de type char alloué à un autre moment
    Les 2 pointeurs possèdent tous deux une zone mémoire distincte. Il n'y a donc aucune différence entre free(t) et free(t[i]). Chaque fonction libère la zone mémoire concernée.

    Citation Envoyé par siempre Voir le message
    Si on fait free(t) ceci implique free(t[i]) ?
    Eh non (comment le compilo sait que dans la zone "t" tu y as stocké d'autres pointeurs eux-aussi alloués ???)
    Pire, la zone allouée pour t contient des pointeurs pointant vers diverses zones allouées pour les différents t[x]. En libérant t sans libérer t[x], on perd ces pointeurs mais les zones ne sont pas libérées => mémoire perdue (et sous Windows, il faut redémarrer l'ordi pour la retrouver !!!)

  2. #22
    Membre à l'essai
    Inscrit en
    Août 2009
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 16
    Points : 18
    Points
    18
    Par défaut
    J'ai ajouté des améliorations:

    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    #include <stdio.h>
    #include <string.h>
     
    #define NOMBRE_CARACTERES_PAR_LIGNE_MAX	100
     
    typedef enum
    {
    	CODE_ERREUR_SUCCES = 0,
    	CODE_ERREUR_ECHEC = 1,
    }CodeErreur;
     
    int allocation(int N)
    {
    	CodeErreur codeErreur = CODE_ERREUR_ECHEC;
     
    	char** t = (char**) malloc(N * sizeof (*t));
     
    	if (t)
    	{
    		FILE* fp = fopen("exemple.txt", "r");
     
    		if (fp)
    		{
    			char s[NOMBRE_CARACTERES_PAR_LIGNE_MAX];
    			char attribut[NOMBRE_CARACTERES_PAR_LIGNE_MAX];
     
    			int i;
    			int j;
     
    			//copier le contenu du fichier dans le tableau
    			for (i = 0; i < N; i ++)
    			{
    				if (fgets(s, NOMBRE_CARACTERES_PAR_LIGNE_MAX, fp))
    				{
    					if (sscanf(s, "%s", attribut) > 0)
    					{
    						t[i] = strdup(attribut);
     
    						if (t[i])
    						{
    							printf("%s\n", t[i]);	
    						}
    						else
    						{
    							printf("Pas assez de memoire disponible pour dupliquer la chaine.\n");
     
    							break;
    						}
    					}
    					else
    					{
    						printf("Echec de sscanf().\n");
     
    						break;
    					}
    				}
    				else
    				{
    					printf("Echec de fgets().\n");
     
    					break;
    				}
    			}
     
    			if (i == N)
    			{
    				//afficher le contenu de tableau
    				for (j = 0; j < N; j ++)
    				{
    					printf("j = %d, s = %s\n", j, t[j]);
    				} 
     
    				codeErreur = CODE_ERREUR_SUCCES;
    			}
     
    			fclose(fp);
    		}
    		else
    		{
    			printf("impossible d'ouvrir le fichier\n");
    		}
     
    		free(t);
    	}
    	else
    	{
    		printf("probleme d'allocation\n");
    	}
     
    	return codeErreur;
    }
     
     
    int main(int argc, char* argv[])
    {
    	switch (allocation(5))
    	{
    		case CODE_ERREUR_SUCCES:
    			printf("Succes de allocation()\n");
     
    			break;
     
    		case CODE_ERREUR_ECHEC:
    			printf("Echec de allocation()\n");
     
    			break;
     
    		default:
    			printf("allocation() a retourne un code d'erreur inconnu.\n");
    	}
     
    	return 0;
    }

  3. #23
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par cameleon65 Voir le message
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    #include <stdio.h>
    #include <string.h>
     
    #define NOMBRE_CARACTERES_PAR_LIGNE_MAX	100
     
    typedef enum
    {
    	CODE_ERREUR_SUCCES = 0,
    	CODE_ERREUR_ECHEC = 1,
    }CodeErreur;
     
    int allocation(int N)
    {
    	CodeErreur codeErreur = CODE_ERREUR_ECHEC;
     
    	char** t = (char**) malloc(N * sizeof (*t));
     
    	if (t)
    	{
    		FILE* fp = fopen("exemple.txt", "r");
     
    		if (fp)
    		{
    			char s[NOMBRE_CARACTERES_PAR_LIGNE_MAX];
    			char attribut[NOMBRE_CARACTERES_PAR_LIGNE_MAX];
     
    			int i;
    			int j;
     
    			//copier le contenu du fichier dans le tableau
    			for (i = 0; i < N; i ++)
    			{
    				if (fgets(s, NOMBRE_CARACTERES_PAR_LIGNE_MAX, fp))
    				{
    					if (sscanf(s, "%s", attribut) > 0)
    					{
    						t[i] = strdup(attribut);
     
    						if (t[i])
    						{
    							printf("%s\n", t[i]);	
    						}
    						else
    						{
    							printf("Pas assez de memoire disponible pour dupliquer la chaine.\n");
     
    							break;
    						}
    					}
    					else
    					{
    						printf("Echec de sscanf().\n");
     
    						break;
    					}
    				}
    				else
    				{
    					printf("Echec de fgets().\n");
     
    					break;
    				}
    			}
     
    			if (i == N)
    			{
    				//afficher le contenu de tableau
    				for (j = 0; j < N; j ++)
    				{
    					printf("j = %d, s = %s\n", j, t[j]);
    				} 
     
    				codeErreur = CODE_ERREUR_SUCCES;
    			}
     
    			fclose(fp);
    		}
    		else
    		{
    			printf("impossible d'ouvrir le fichier\n");
    		}
     
    		free(t);
    	}
    	else
    	{
    		printf("probleme d'allocation\n");
    	}
     
    	return codeErreur;
    }
    J'ai ajouté des améliorations:
    Ouaip bon. Déjà t'as oublié de libérer les t[x]. De plus, les types créés sont habituellement nommés "t_xxx" afin de ne pas les confondre avec des variables et le flux stderr n'a pas été créé que pour les pingouins.
    De plus ta gestion des erreurs est efficace mais si t'as 50 cas à évaluer, une fois que tout est correct tu vas te retrouver à programmer complètement à droite de ton écran.
    Je préfère la technique
    - je prends une ressource
    - si la ressource n'est pas disponible j'arrête tout en nettoyant ce qui a déjà été fait
    Certes il y a des répétions d'instruction mais quand tu arrives au travail réel, tu as encore toute la place pour programmer ton algo
    Et on peut éviter ces répétions de code en utilisant un "goto error" judicieusement placé où le bloc error contiendra les instructions de nettoyage (voir discussion sur le goto => http://www.developpez.net/forums/d75.../c/pensez-goto)

  4. #24
    Membre à l'essai
    Inscrit en
    Août 2009
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 16
    Points : 18
    Points
    18
    Par défaut
    J'avais pas oser mettre des goto à la place des break à cause qu'il y a des gens qui n'aime pas.

    Je préfère mettre en majuscule la première lettre d'un type, un peu comme on fait en java.

    S'il y a pleins d'imbrications et on est rendu à programmer le vrai traitement à droite, on peut faire ce que tu as dit ou mettre le traitement dans une fonction [inline], mais là aussi il y a d'autres types d'inconvénients.

    J'ai fait des modifications:

    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define NOMBRE_CARACTERES_PAR_LIGNE_MAX	100
     
    typedef enum
    {
    	CODE_ERREUR_SUCCES = 0,
    	CODE_ERREUR_ECHEC = 1,
    }CodeErreur;
     
    int allocation(int N)
    {
    	CodeErreur codeErreur = CODE_ERREUR_ECHEC;
     
    	char** t = (char**) malloc(N * sizeof (*t));
     
    	if (t)
    	{
    		FILE* fp = fopen("exemple.txt", "r");
     
    		if (fp)
    		{
    			char s[NOMBRE_CARACTERES_PAR_LIGNE_MAX];
    			char attribut[NOMBRE_CARACTERES_PAR_LIGNE_MAX];
     
    			int i;
    			int j;
     
    			//copier le contenu du fichier dans le tableau
    			for (i = 0; i < N; i ++)
    			{
    				if (fgets(s, NOMBRE_CARACTERES_PAR_LIGNE_MAX, fp))
    				{
    					if (sscanf(s, "%s", attribut) > 0)
    					{
    						t[i] = strdup(attribut);
     
    						if (t[i])
    						{
    							printf("%s\n", t[i]);
    						}
    						else
    						{
    							fprintf(stderr, "Pas assez de memoire disponible pour dupliquer la chaine.\n");
     
    							goto LIBERATION_MEMOIRE;
    						}
    					}
    					else
    					{
    						fprintf(stderr, "Echec de sscanf().\n");
     
    						goto LIBERATION_MEMOIRE;
    					}
    				}
    				else
    				{
    					fprintf(stderr, "Echec de fgets().\n");
     
    					goto LIBERATION_MEMOIRE;
    				}
    			}
     
    			//afficher le contenu de tableau
    			for (j = 0; j < N; j ++)
    			{
    				printf("j = %d, s = %s\n", j, t[j]);
    			} 
     
    			codeErreur = CODE_ERREUR_SUCCES;
     
    			LIBERATION_MEMOIRE:
    				for (; i >= 0; i --)
    				{
    					free(t[i]);
    				}
     
    				fclose(fp);
    		}
    		else
    		{
    			fprintf(stderr, "impossible d'ouvrir le fichier\n");
    		}
     
    		free(t);
    	}
    	else
    	{
    		fprintf(stderr, "probleme d'allocation\n");
    	}
     
    	return codeErreur;
    }
     
    int main(int argc, char* argv[])
    {
    	switch (allocation(5))
    	{
    		case CODE_ERREUR_SUCCES:
    			printf("Succes de allocation()\n");
     
    			break;
     
    		case CODE_ERREUR_ECHEC:
    			printf("Echec de allocation()\n");
     
    			break;
     
    		default:
    			printf("allocation() a retourne un code d'erreur inconnu.\n");
    	}
     
    	return 0;
    }

Discussions similaires

  1. Problème d'allocation de tableau dynamique
    Par DuffNut dans le forum Langage
    Réponses: 4
    Dernier message: 26/10/2011, 11h17
  2. Réponses: 5
    Dernier message: 06/07/2011, 15h35
  3. Réponses: 4
    Dernier message: 25/03/2010, 22h11
  4. [Débutant][Win32] Problème d'allocation de tableau de FILE
    Par Patchanka dans le forum Visual C++
    Réponses: 8
    Dernier message: 06/04/2009, 10h49
  5. Réponses: 5
    Dernier message: 06/02/2007, 09h26

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