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 :

grr.. encore un pb d'alloc :s (realloc & strncat)


Sujet :

C

  1. #21
    Membre confirmé

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Par défaut
    Citation Envoyé par ramislebob
    Quand j'initialise mon char* à NULL, plantage :s
    en revanche un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        char *confSrc = (char *) malloc(1);
        confSrc[0]=0x0;
    permet une initialisation à vide.
    bref, realloc semble ne s'appliquer QUE à un espace mémoire alloué par malloc.
    Sous Windows, un n'est pas équivalent au malloc ci-dessus si on utilise des realloc après !
    l'initialisation à NULL (ou 0x0) provoque un plantage de la CMD...


    Citation Envoyé par Emmanuel Delahaye
    Il faut vérifier si malloc() a réussi avant d'utiliser le bloc alloué.
    oups... j'ai oublié de mettre de la robustesse la-dessus :s
    que peut on faire quand on a un échec sur un malloc ou un realloc ? (à part retester n fois)
    je repose ma question : cé koi que vous appelez cast ?

  2. #22
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Sous Windows, un
    n'est pas équivalent au malloc ci-dessus si on utilise des realloc après !
    l'initialisation à NULL (ou 0x0) provoque un plantage de la CMD...
    Si tu parles de programmation window orienté C++, le malloc est l'équivalent d'un new et le free d'un delete.

    L'écriture que tu as faîte signifie que ton pointeur pointe sur une valeur non valide. C'est cela qu'il faut faire quand tu ne désires pas encore pointer sur une adresse spécifique ou si tu n'as pas encore besoin d'allouer un espace mémoire.

    remarque:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *confSrc = (char *) malloc(1);
    Vaut mieux faire cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *confSrc = malloc(sizeof(*confSrc));

  3. #23
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par ramislebob
    Sous Windows, un n'est pas équivalent au malloc ci-dessus si on utilise des realloc après !
    l'initialisation à NULL (ou 0x0) provoque un plantage de la CMD...
    Ah si ! Ce genre de chose est utilisé dans les boucles, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    char *text = NULL;
    size_t size = 1;
     
    while (/* ... */)
    {
      void *tmp = NULL;
     
      size <<= 2;
      tmp = realloc (text, sizeof (*text) * size)
      if (tmp)
      {
        text = tmp;
      }
    }
    Si ça plante, c'est surement que tu as un débordement quelque part qui écrase les structures de données internes servant à gérer la mémoire.

    Un cast c'est la même chose qu'un transtypage.

  4. #24
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par ramislebob
    que peut on faire quand on a un échec sur un malloc ou un realloc ? (à part retester n fois)
    C'est une erreur fatale et on doit quitter le programme (sauf utilisation de techniques sophistiquees inutiles dans ton cas).

    je repose ma question : cé koi que vous appelez cast ?
    Merci d'eviter le SMS: 'qu'appelez-vous un cast?' (ou transtypage, pour etre pedant).
    C'est forcer un changement de type d'une variable, d'un retour de fonction, etc.
    malloc() renvoit un void * que tu castes en (char *). En C, c'est mal, car c'est inutile (tout pointeur void est conforme a un pointeur de n'importe quel type) et cela cache la non-inclusion de stdlib.h.

  5. #25
    Membre confirmé

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Par défaut
    Citation Envoyé par homeostasie
    Si tu parles de programmation window orienté C++, le malloc est l'équivalent d'un new et le free d'un delete.
    nan j'ai jamais fais de C++, uniquement du C.

    Citation Envoyé par gege2061
    Si ça plante, c'est surement que tu as un débordement quelque part qui écrase les structures de données internes servant à gérer la mémoire.
    ben je comprends pas où alors :s
    je vais remettre mon code au complet, si quelqu'un peut me dire pourquoi quand je met un NULL au lieu d'un malloc ça plante...
    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
     
    #ifdef __cplusplus
        #error Be sure you are using a C compiler...
    #endif
     
    #ifndef WIN32
        #define WIN32
    #endif
     
    #ifndef RENFOTO
        #define RENFOTO
        #include <stdio.h> 
        #include <stdlib.h>
        #include <sys/types.h>
        #include <errno.h> // perror
        #include <strings.h> // strlen, strcpy,...
        #include <string.h> // bzero...
        #include <unistd.h> // R_OK
        #include <fcntl.h> // O_RDONLY O_WRONLY
    #endif
     
    #ifdef WIN32
        #include <windows.h>
    #endif
     
     
    #define filePath "C:\\blabla.txt"
     
    int existFile(char *fichier);
    int myRealloc(void ** ppData, size_t newSize);
    void loadTextFile(char *name, char **stockage);
     
    // Fonction Principale :p
    int main(int argc, char *argv[], char **envp){
        char *fichier=NULL;//(char *) malloc(1);
    //    fichier[0]=0x0;
        loadTextFile(filePath, &fichier);  
        printf("%s",fichier);
        free(fichier);
        exit(0);
    }
     
    /** Test d'existance d'un fichier */
    int existFile(char *fichier){
     
        if ( access(fichier, F_OK)==-1 ){
            printf("Error Access File : %s :\\\n",fichier);
            return -1;
        }
        else
            return 0;
    }
     
    int myRealloc(void ** ppData, size_t newSize){
        void *pTmp = realloc(*ppData, newSize);
        if(pTmp == NULL)
    	return -1;	
        else{
    	*ppData = pTmp;
    	return 0;
        }
    }
     
    void loadTextFile(char *name, char **stockage){
        #define tailleBuffer 10
        char buffer[tailleBuffer];
        FILE *file;
        int NbLu;
        int taille=strlen(*stockage);
    //    printf("TAille initiale : %i\n",taille);
     
        if (existFile(name)==-1){
    	printf("Accès impossible au fichier %s...\n",name);
    	printf("Existe t'il vraiment... :s");
    	exit(1);
        }
     
        if((file=fopen(name, "r")) == NULL){
    	printf("Ouverture impossible du fichier %s :s\n",name);	
    	exit(1);
        }
     
        while( (NbLu=fread(buffer, 1, tailleBuffer, file)) != 0){
    	taille+=NbLu;
    	if (myRealloc((void **)stockage,taille+1)==-1){
    	    free(*stockage);
    	    printf("Error Realloc :s\n");
    	    exit(1);
    	}
    //	*stockage=(char *) realloc(*stockage,taille+1);
    	strncat(*stockage,buffer,NbLu);
    	(*stockage)[taille-1]=0x0;
        }
        fclose(file);
    }
    Pourquoi ça fait planter la CMD ?

  6. #26
    Membre confirmé

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Par défaut
    Citation Envoyé par DaZumba
    C'est une erreur fatale et on doit quitter le programme (sauf utilisation de techniques sophistiquees inutiles dans ton cas).


    Merci d'eviter le SMS: 'qu'appelez-vous un cast?' (ou transtypage, pour etre pedant).
    C'est forcer un changement de type d'une variable, d'un retour de fonction, etc.
    malloc() renvoit un void * que tu castes en (char *). En C, c'est mal, car c'est inutile (tout pointeur void est conforme a un pointeur de n'importe quel type) et cela cache la non-inclusion de stdlib.h.
    sorry pour le langage SMS :s
    je savais pas qu'un transtypage s'appelle un cast :s (ça me fais penser à diffusion, je vois pas trop le rapport avec un transtypage..)

  7. #27
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par ramislebob
    Sous Windows, un n'est pas équivalent au malloc ci-dessus si on utilise des realloc après !
    l'initialisation à NULL (ou 0x0) provoque un plantage de la CMD...
    Jamais constaté ça. Montre le code qui a ce comportement.
    oups... j'ai oublié de mettre de la robustesse la-dessus :s
    que peut on faire quand on a un échec sur un malloc ou un realloc ? (à part retester n fois)
    On peut effectivement recommencer un peu plus tard (sleep(), Sleep(), selon le système...). En cas d'echec définitif, remonter l'info aux couches supérieures qui prendront les décisions qui s'imposent. Ca dépend qui et impliqué.
    je repose ma question : cé koi que vous appelez cast ?
    Je crois qu'on t'a déjà répondu : conversion d'un type dans un autre. C'est rarement utile et souvent le signe d'un codage de chacal.

  8. #28
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par ramislebob
    sorry pour le langage SMS :s
    je savais pas qu'un transtypage s'appelle un cast :s (ça me fais penser à diffusion, je vois pas trop le rapport avec un transtypage..)
    cast = rôle (casting).

    Utiliser un transtypage, c'est changer le rôle d'un type.

  9. #29
    Membre confirmé

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    cast = rôle (casting).

    Utiliser un transtypage, c'est changer le rôle d'un type.
    merci pour la précision
    Citation Envoyé par Emmanuel Delahaye
    Jamais constaté ça. Montre le code qui a ce comportement.
    je l'ai déjà mis un peu plus haut, je le remet ici :
    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
     
    #ifdef __cplusplus
        #error Be sure you are using a C compiler...
    #endif
     
    #ifndef WIN32
        #define WIN32
    #endif
     
    #ifndef RENFOTO
        #define RENFOTO
        #include <stdio.h> 
        #include <stdlib.h>
        #include <sys/types.h>
        #include <errno.h> // perror
        #include <strings.h> // strlen, strcpy,...
        #include <string.h> // bzero...
        #include <unistd.h> // R_OK
        #include <fcntl.h> // O_RDONLY O_WRONLY
    #endif
     
    #ifdef WIN32
        #include <windows.h>
    #endif
     
     
    #define filePath "C:\\dotclear\\conf\\dotclear.ini.in"
     
    int existFile(char *fichier);
    int myRealloc(void ** ppData, size_t newSize);
    void loadTextFile(char *name, char **stockage);
     
    // Fonction Principale :p
    int main(int argc, char *argv[], char **envp){
        char *fichier=NULL;//(char *) malloc(1);
    //    fichier[0]=0x0;
        loadTextFile(filePath, &fichier);  
        printf("%s",fichier);
        free(fichier);
        exit(0);
    }
     
     
     
     
    /** Test d'existance d'un fichier */
    int existFile(char *fichier){
     
        if ( access(fichier, F_OK)==-1 ){
            printf("Error Access File : %s :\\\n",fichier);
            return -1;
        }
        else
            return 0;
    }
     
    int myRealloc(void ** ppData, size_t newSize){
        void *pTmp = realloc(*ppData, newSize);
        if(pTmp == NULL)
    	return -1;	
        else{
    	*ppData = pTmp;
    	return 0;
        }
    }
     
    void loadTextFile(char *name, char **stockage){
        #define tailleBuffer 10
        char buffer[tailleBuffer];
        FILE *file;
        int NbLu;
        int taille=strlen(*stockage);
    //    printf("TAille initiale : %i\n",taille);
     
        if (existFile(name)==-1){
    	printf("Accès impossible au fichier %s...\n",name);
    	printf("Existe t'il vraiment... :s");
    	exit(1);
        }
     
        if((file=fopen(name, "r")) == NULL){
    	printf("Ouverture impossible du fichier %s :s\n",name);	
    	exit(1);
        }
     
        while( (NbLu=fread(buffer, 1, tailleBuffer, file)) != 0){
    	taille+=NbLu;
    	if (myRealloc((void **)stockage,taille+1)==-1){
    	    free(*stockage);
    	    printf("Error Realloc :s\n");
    Ce fichier compile, à l'exécution il plante. (seul truc à changer : ligne 26, mettre un fichier texte qui existe sur votre machine )

    Par contre, si dans le main on remplace le NULL par le malloc (ligne 34, 35 à décommenter) il marche nickel !

    Alors où est le problème si ce n'est pas le NULL ?

  10. #30
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par ramislebob
    uniquement du C.
    je vais remettre mon code au complet, si quelqu'un peut me dire pourquoi quand je met un NULL au lieu d'un malloc ça plante...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main(int argc, char *argv[], char **envp)
    {
        char *fichier=NULL;
        loadTextFile(filePath, &fichier);  
    <...>
    }
     
    void loadTextFile(char *name, char **stockage)
    {
        int taille=strlen(*stockage);
    <...>
    Pourquoi ça fait planter la CMD ?
    C'est sûr que *stockage avec stockage == NULL, ça va pas le faire. On t'a déjà expliqué que la taille alloué devait être gérée à part...

  11. #31
    Membre confirmé

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    C'est sûr que *stockage avec stockage == NULL, ça va pas le faire. On t'a déjà expliqué que la taille alloué devait être gérée à part...
    Oki, j'avais pas vu :s
    pour la taille je la traite à part sauf ici. j'ai mis une struct comme vous le suggérez mais pour un string ce n'est pas necessaire.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 3
    Dernier message: 15/06/2010, 22h11
  2. Programmer encore en VB 6 c'est pas bien ? Pourquoi ?
    Par Nektanebos dans le forum Débats sur le développement - Le Best Of
    Réponses: 85
    Dernier message: 10/03/2009, 14h43
  3. Réponses: 4
    Dernier message: 03/12/2002, 16h47
  4. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14
  5. Allocation de ressources
    Par Eric Pasquier dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 08/10/2002, 09h19

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