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 :

Reallocation de mémoire pour un tableau


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut Reallocation de mémoire pour un tableau
    Bonjour,

    Je suis tombé sur une erreur de ce type:

    error: incompatible types in assignment of 'void*' to 'variable* [0]'


    Mon but serait d'avoir un tableau de structure et de pouvoir ajouter des cases à ce tableau pendant l'exécution.

    Voici mon code:

    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
     
     
    struct variable
    {
        int utilisee;
        int typeVariable;
        int valeurChiffre;
        char valeurLettre;
        char valeurChaine;
    };
     
    variable *Variables[0];
     
     //L'erreur est ici.
    Variables = realloc(Variables, 2 * sizeof(variable));
    J'ai donc cherché mon erreur seul et à l'aide de Google mais je n'ai pas trouvé, c'est pourquoi je vous demande de l'aide

    Et ce que je ne comprend pas non plus c'est que j'ai tenté de compiler ce code donné sur cette page soit:

    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
     
     
    int * tabentier;
    /* Création d'un tableau de 3 entiers */
    tabentier = calloc ( 3 , sizeof(int) );
     
    tabentier[0] = 1;
    tabentier[1] = 2;
    tabentier[2] = 3;
     
    /* Ajout d'un element au tableau */
    tabentier = realloc (tabentier, 4 * sizeof(int) );
     
    tabentier[3] = 4;
     
    for ( i = 0 ; i < 3 ; i++ )
    {
         printf(" tabentier[%d] = %d \n", i , tabentier[i] );
    }
    Mais il ne compile pas et me donne la même erreur (je n'ai pas mis les vérifications d'allocations pour que ça soit plus clair )

    Voilà, j'espère que vous pourrez m'aider,
    Merci d'avance

    Neyort.

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    C'est encore moi, je viens de trouver la solution à mon problème!

    J'avais juste oublié la petite étoile montrant qu'il s'agit d'un pointeur et ai fait un cast vers mon type de variable.

    Voici le code pour ceux qui auraient la même erreur que moi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    struct variable
    {
        int utilisee;
        int typeVariable;
        int valeurChiffre;
        char valeurLettre;
        char valeurChaine;
    };
     
    variable *Variables[0];
     
     //La modification
    *Variables = (variable*)realloc(Variables, 2 * sizeof(variable));
    Neyort

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Tu m'as l'air de compiler en C++ toi
    Sinon tu aurais dû rajouter le mot clé struct comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct variable *Variables[N];
    et n'aurais pas eu besoin du cast devant realloc().

    Mais attention, cette syntaxe sert à créer un tableau de N pointeurs où chaque case Variables[i] contiendra un pointeur sur struct variable.
    Ici, tu lui mets une taille nulle, il ne pourra donc jamais rien contenir.

    Pour ton cas : un simple pointeur struct variable *Variables; suffit.

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Salut!

    Merci à toi Winjerome pour ta réponse!

    En effet, tu as raison il est plus pratique de mettre directement un struct devant la déclaration de la structure plutôt que de faire un cast à chaque fois

    Merci de cette remarque



    Neyort

  5. #5
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    ATTENTION !!!


    Un "realloc" peut échouer...

    Dans ce cas, avec la manière écrite, il n'y a strictement aucun moyen de récupérer ou libérer la mémoire déjà allouée... puisque realloc renverra NULL, et que le pointeur sera écrasé...

    La manière correcte et sûre d'utiliser un realloc est :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    variable *Variables, *tmp;
    int   NVars;
     ....
     
    if ( (tmp = realloc ( Variables, ((NVars+x)*sizeof(variable)) )) != NULL )
     {
         Variables = tmp ;
         NVars = NVars + x ;
     }

    Dans ce cas, si l'allocation échoue, on aura toujours ce qui avait été alloué avant pointé par le pointeur Variables. Là, on peut en faire ce qu'on veut (continuer, ou libérer et abandonner)
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Salut

    Oui c'est vrai, mais est-il comme malloc, c'est à dire dépendant de la mémoire vive?

    En fait, je pensais qu'il dépendait de la mémoire, c'est à dire qu'il échouait seulement si la mémoire vive était saturée

    Mais faut pas m'en vouloir un

    Merci pour ta précision en tout cas

    Neyort

  7. #7
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Neyort Voir le message
    Oui c'est vrai, mais est-il comme malloc, c'est à dire dépendant de la mémoire vive?

    En fait, je pensais qu'il dépendait de la mémoire, c'est à dire qu'il échouait seulement si la mémoire vive était saturée
    Euh ...

    Les 2 se comportent exactement de la même manière.. La différence est qu'un alloc alloue un bloc de la taille désirée là où il peut..

    Etant donné que "free" ne libère pas vraiment la mémoire déjà allouée (j'avais fait un schéma il y a un certain temps qu'il faudrait rechercher), sauf si c'est la dernière allocation qu'on libère, un realloc peut bouger l'ensemble du bloc pour le mettre soit à une adresse plus basse, soit à une adresse plus haute, suivant les tailees respectives des "trous" et de ce qui est demandé...

    Je rechercherais le schéma... Mais c'est assez simple à comprendre :

    Si ta mémoire au départ est :

    --------------


    Que tu alloues d'abord 5, puis 7, puis libère les 5, tu auras :

    -------------- -------

    Il est quasi-impossible de faire que en libérant le 5 on "tasse" le reste, pusique les pointeurs sont stockés dans des variables utilisateurs, qui à ce moment-là ont peu de chances d'être passées en paramètres pour être mises à jour...

    Au bout d'un certain temps - ou d'un certain nombres de fonctions - on a donc en mémore une partie contigue (le code loadé plus les varaibles intiiales), plus une série de "trous" et de "parties contigues"..

    Si par exemple dans le cas ci-dessus on veut réallouer le bloc de 5, tout dépendra de la taille demandée... Si la taille est <= 5 l'algo interne fera qu'on ira combler (éventuellement partiellement) le "trou"... Si la taille demandée est 6 ou plus, l'allocation ira réserver une zone après le bloc de 7.. Si on n'avait pas libéré le bloc de 5, mais qu'on demande le realloc à une taille de 6 ou plus, il ira là-aussi le mettre après le bloc de 7, et donc il réservera la place, puis copiera ce qu'il avait à l'emplacement du bloc de 5 en début du nouveau bloc, indiquant ensuite que il y a un "trou" de 5 à l'ancien emplacement..


    C'est ce qui fait que lorsqu'on a des données qui s'ajoutent les unes après les autres il est - sauf contraintes extenres par rapport à l'algorithme par exemple - recommandé d'utiliser une liste chaînée plutôt qu'un tableau : les "trous" créés par la destruction d'un élément correspondront aux "blocs" nécessités par la création d'un élément... Si d'un autre côté on a crée un tableau, et qu'on le réalloue systématiquement - et si il y a des allocations entre temps - alors on va forcément créer des "trous" de plus en plus grands (si l'on augmente la taille du tableau)... On va donc consommer de la mémoire pour "rien", et on peut arriver à faire "exploser" la mémoire (et en plus prendre de plus en plus de temps, car il faudra copier le taleau à chaque realloc), alors que dans le cas de la liste chaînée on utilise "au mieux" les "trous" crées et en plus on ne copie rien...


    PS: bon, j'ai pas retrouvé la discussion et le schéma intial (archivé, de l'année 2007), mais une référence et 2 posts plus explicatifs en 2008: ici et
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Merci énormément pour ta réponse très claire et détaillée!

    Si j'ai bien compris (dis moi si je me trompe), le "bourrage" complet de la RAM peut aller plus vite qu'on ne le pense en faisant sans cesse des malloc sans rien libérer.

    Et dans le cas des realloc, il pourra là aussi, créer des "trous" qui seront des zones de la RAM trop petites pour contenir quelque chose et l'accumulation de ces "trous" créerait un saturage complet de la RAM.

    C'est pourquoi il est impératif de gérer les retours des pointeurs et plus précisément la gestion des erreurs sur les allocations de mémoire


    Merci une nouvelle fois de m'avoir mieux expliqué le fonctionnement de l'allocation mémoire!

    EDIT:

    Peux-tu m'indiquer à quoi correspond la variable 'x' dans ton code? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if ( (tmp = realloc ( Variables, ((NVars+x)*sizeof(variable)) )) != NULL )


    Neyort

  9. #9
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Neyort Voir le message
    Si j'ai bien compris (dis moi si je me trompe), le "bourrage" complet de la RAM peut aller plus vite qu'on ne le pense en faisant sans cesse des malloc sans rien libérer.
    Dans ce cas-là, pas vraiment "plus vite qu'on ne le pense".. Enfin, ça dépend comment tu penses

    La mémoire, qu'elle soit vive ou sur disque, a une limite finale : somme de la capacité mémoire vive (DRAM) + taille du swap sur le DD... = X Mo (ou Go)

    Ce qui est "consommé" est : somme des mémoires allouées à tous les processus tournants (y compris ceux du système) et leurs variables = Y Mo (ou Go)

    Si Y >= X, alors on a atteint la limite, et le système/le programme va crasher car il lui "manquera" des informations ...

    Si ton programme ne fait que des allocs sans jamais rien libérer, ça peut ne rien faire si tes allocs sont petits, ta DRAM ou ton swap sont très grands, et ton programme ne tourne pas longtemps, mais dans tous les autres cas oui tu vas augmenter jusqu'à atteindre la limite...

    Par contre, TON programme aura une zone occupée contiguement...


    Citation Envoyé par Neyort Voir le message
    Et dans le cas des realloc, il pourra là aussi, créer des "trous" qui seront des zones de la RAM trop petites pour contenir quelque chose et l'accumulation de ces "trous" créerait un saturage complet de la RAM.
    Si tu n'as pas créé de trous en faisant des "free", et que ton realloc est toujours sur le dernier buffer alloué (celui qui est "au bout" de la chaîne indiquée dans les posts précédents), tu seras dans la même situation que ci-dessus : tu croîtras régulièrement jusqu'à atteindre la limite..

    Si tu as créé des trous pas assez grands pour les reallocs suivants, ou si tu alloué d'autres tableaux entre-temps que tu n'as pas encore libéré, le realloc ira ajouter une zone correspondante à la nouvelle taille à l'extrémité de la zone allouée, et donc ta mémoire ne grossira pas "suivant ce qui est demandé", mais par "bonds", et donc augmentera beaucoup plus vite que un simple calcul laisserait supposer..



    Citation Envoyé par Neyort Voir le message
    C'est pourquoi il est impératif de gérer les retours des pointeurs et plus précisément la gestion des erreurs sur les allocations de mémoire
    Encore une fois tout dépend de l'utilisation, mais il est bon de prendre les bonnes habitudes, même si dans un cas précis on n'en a pas besoin (une alloc dans un prgramme tournant une seule fois)



    Citation Envoyé par Neyort Voir le message
    Peux-tu m'indiquer à quoi correspond la variable 'x' dans ton code? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if ( (tmp = realloc ( Variables, ((NVars+x)*sizeof(variable)) )) != NULL )
    rien, jute une quantité dépendant de ce que fait ton prog.. En général c'est 1 (l'équivalent du "new", ajouter un élément), mais ça peut être une quantité pré-décidée pour éviter de faire trop d'allocs (2, 3, le nombre d'or, une quantité estimée raisonnable pour le programme, quoi ..)
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Salut,

    Merci une nouvelle fois à toi pour toutes tes explications!

    Donc en résumé il faudrait que j'utilise plutôt ce code-ci :
    (pas taper un )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        variable *Variables;
        variable *tmp;
        int NVars;
     
        if( (tmp = realloc ( Variables, ((NVars+1)*sizeof(variable)) )) != NULL )
        {
             Variables = tmp;
             NVars = NVars+1;
        }
    Mais je suppose que ce n'est pas correct car l'erreur :
    error: invalid conversion from 'void*' to 'variable*' [-fpermissive]|

    M'indique que la ligne de la condition n'est pas correcte.
    D'où mon 'cast' des précédents posts

    Comment faire?

    Et donc (enfin si j'ai bien compris cette fois^^') ce code regarde si l'on peut réallouer de la mémoire correctement, si non on ne fait rien (on rajoutera un else pour les erreurs). Et si tout se passe bien on place la nouvelle struture dans 'Variables' et on incrémente le nombre de variables existants NVars.

    Suis-je complètement à côté de la plaque ou ai-je compris? ^^

    Merci à toi pour toutes tes explications très détaillées!

    Neyort

  11. #11
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Neyort Voir le message
    Mais je suppose que ce n'est pas correct car l'erreur :
    error: invalid conversion from 'void*' to 'variable*' [-fpermissive]|

    M'indique que la ligne de la condition n'est pas correcte.
    D'où mon 'cast' des précédents posts
    Je pense que cela vient de ta définition de la structure..

    La manière la plus souple/élégante/correcte/sans soucis de faire est :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct pvariable
    {
        int utilisee;
        int typeVariable;
        int valeurChiffre;
        char valeurLettre;
        char valeurChaine;
    } varaible ;


    Citation Envoyé par Neyort Voir le message
    Et donc (enfin si j'ai bien compris cette fois^^') ce code regarde si l'on peut réallouer de la mémoire correctement, si non on ne fait rien (on rajoutera un else pour les erreurs). Et si tout se passe bien on place la nouvelle struture dans 'Variables' et on incrémente le nombre de variables existants NVars.
    Tout à fait

    Sur le point souligné on peut préciser un peu :

    Suivant ce que fait ton programme et ses contraintes, si la ré-allocation échoue, tu peux soit continuer tel quel (puisque tu n'as touché ni au pointeur ni au nombre d'élements), soit donner un message d'erreurs, puis libérer, soit ce que tu veux...

    Si par exemple tu lis des données, tu peux re-boucler .. Eventuellement tu pourras ne plus avoir d'échec (si par exemple un autre processus a libéré de la mémoire). Ou bien annuler tout, ....

    C'est en fonction de tes contraintes..

    Mais c'est effectivement la bonne manère de faire..
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Merci une nouvelle fois je n'ai plus cette erreur de structure et je commence à avoir un code propre grâce à toi!

    Il me reste néanmoins deux questions:

    -Pour mon else, dans le cas où il se passerais une erreur ou même pour la fin du programme il me faut libérer la mémoire. Il me suffit d'utiliser un free non? Car Tu m'as dis que les free n'étaient pas car tu m'as dis:

    Citation Envoyé par souviron34
    Si tu n'as pas créé de trous en faisant des "free"
    Je dois en conclure qu'ils ne sont pas conseillés?

    Ma deuxième question porte sur cette erreur:

    error: invalid conversion from 'void*' to 'variable* {aka pvariable*}' [-fpermissive]|

    Sur cette fameuse condition:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if( (tmp = realloc ( Variables, (nombreDeVariables*sizeof(variable)) )) != NULL )
    J'ai pourtant bien mis ta nouvelle structure

    Merci à toi pour toute l'aide que tu m'apporte!

    Neyort

  13. #13
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Neyort Voir le message
    -Pour mon else, dans le cas où il se passerais une erreur ou même pour la fin du programme il me faut libérer la mémoire. Il me suffit d'utiliser un free non? Car Tu m'as dis que les free n'étaient pas car tu m'as dis:

    Je dois en conclure qu'ils ne sont pas conseillés?
    Non, au contraire, ils sont conseillés - quand on doit le faire. Par contre, il est sain de toujours coupler avec la remise à NULL du pointeur :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
      free(tab), tab=NULL ;
    ou

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      free(tab);
      tab=NULL ;

    Ce que je voulais dire, c'est que dans un programme xxx, il est possible que l'on fasse des réallocations sur un tableau X alors qu'entre-temps on n'a pas libéré quoi que ce soit..

    C'est ce que je montrais dans les exemples : de manière générale, un programme qui fait des allocs et des frees, ou des allocs et des reallocs , créera des "trous", c'est tout... Il faut juste en être conscient...



    Citation Envoyé par Neyort Voir le message
    Ma deuxième question porte sur cette erreur:

    error: invalid conversion from 'void*' to 'variable* {aka pvariable*}' [-fpermissive]|

    Sur cette fameuse condition:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if( (tmp = realloc ( Variables, (nombreDeVariables*sizeof(variable)) )) != NULL )
    En général pour être sûr il vaut mieux mettre les flags "-WStrictProtoypes", et souvent "-ANSI"..

    Dans ton cas, je ne sais pas les autres options que tu as, ni avec quelle version de la libc tu tournes, mais peut-être que tu peux écrire avec le cast :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if( (tmp = (variable *) realloc ( Variables, (nombreDeVariables*sizeof(variable)) )) != NULL )
    Néanmoins, attention : dans ton realloc, le nombre doit être "nombreDeVariables+1" (ou +x)...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  14. #14
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Merci une nouvelle fois de ta réponse

    Je n'ai en effet plus d'erreur mais le programme ne passe jamais la condition :/

    En effet, j'ai donc ce code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    variable *tmp = NULL;
    if( (tmp = (variable*)realloc(Variables, ((nombreDeVariables+1)*sizeof(variable))) ) != NULL )
                {
                    printf("Création d'une variable\n");
                    nombreDeVariables++;
                }
     
                else
                printf("Erreur pour la création d'une variable");
    J'ai donc testé ce code et il m'affiche toujours le message "Erreur pour la création d'une variable"

    Je ne comprend pas... :/

    Merci de votre aide,

    Neyort

  15. #15
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    ben faut voir ....

    Que vaut nombreDeVariables avant l'appel et le pointeur Variables ??

    J'espère que le nombre a été intiailisé quelque part.... (à zéro si c'est la première fois et que la dimaension initiale est nulle..), et le pointeur à NULL...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  16. #16
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Salut

    Alors, nombreDeVariables vaut 0 (elle est initialisée à 0).
    Quant à mon tableau de structure, il ressemble actuellement à ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    typedef struct pvariable
    {
        int utilisee;
        int typeVariable;
        int valeurChiffre;
        char valeurLettre;
        char valeurChaine;
    } variable;
     
    variable *Variables[0];
    J'ai la grande impression de m'être lourdement trompé quelque part mais je ne vois pas trop où, car mon but est de créer un tableau contenant dans chacune de ses case une structure.

    Merci d'avance,

    Neyort

  17. #17
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Neyort Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    variable *Variables[0];
    C'est là que ça se passe

    Attention !!!!! Avant de vouloir faire des choses compliquées, il faut absolument maîtriser les pointeurs, les tableaux, et les variables..

    Quand je vois que ce soit cette déclaration ou un "char ValeurChaine", je me pose des questions sur tes connaissances, parce que une chaîne sera indiquée par un pointeur. (qu'il faudra allouer et assigner, via sprintf, strcat, sscanf, strcpy, ou autre, ou copier par strdup).. Un char contirendra.. un caractère, simplement...


    Exemple :
    Code C : 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
     
    typedef struct pvariable
    {
        int utilisee;
        int typeVariable;
        int valeurChiffre;
        char valeurLettre;
        char *valeurChaine;
    } variable;
     
    variable *Variables=NULL, *tmp=NULL ;
    int       NVar = 0, i ;
     
    for ( i = 0; i < 10 ; i++ )
    {
       if ( (tmp = (variable *) realloc ( Variables, (NVar+1)*sizeof(variable) )) != NULL )
           {
               Variables = tmp ;
               Variables[NVar].utilisee = 0 ;
               Variables[NVar].typevariable = i ;
               Variables[NVar].valeurchaine = NULL ;
               ....
               NVar = NVar + 1 ;
           } 
    }
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  18. #18
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Merci de m'avoir répondu

    Alors en fait je pense que tu as raison, c'est que je me suis complètement emmêler les pinceaux^^' Je mélange les pointeurs sur les tableaux et sur les chaines :/

    Quant au code, celui-ci ne fonctionne pas (le pointeur tmp est toujours égal à nul)

    Salutations,

    Neyort

  19. #19
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Neyort Voir le message
    Quant au code, celui-ci ne fonctionne pas (le pointeur tmp est toujours égal à nul)
    Montre ton code
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  20. #20
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Salut,

    Tout d'abord voici ma déclaration de structure et les variables:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    typedef struct pvariable
    {
        int utilisee;
        int typeVariable;
        int valeurChiffre;
        char valeurLettre;
        char *valeurChaine;
    } variable;
     
    int nombreDeVariables = 0;
    variable *Variables = NULL;
    Ensuite suivant une variable, je passe à une fonction 'DeclarationVariable' les paramètres suivants: typeVariable (un int, pas de problème là dessus):

    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
     
    int DeclarationVariable(int typeVariable)
    {
        variable *tmp = NULL;
    /*Je précise que cette condition fonctionne à chaque fois, c'est la seconde qui pose problème ;)*/
        if(typeVariable == varChiffre)
        {
                if( (tmp = (variable*)realloc(Variables, ((nombreDeVariables+1)*sizeof(variable))) ) != NULL )
                {
                    Variables = tmp;
                    Variables[nombreDeVariables].typeVariable = varChiffre;
                    Variables[nombreDeVariables].utilisee = 1;
                    Variables[nombreDeVariables].valeurChiffre = 0;
                    printf("Création d'une variable\n");
                    nombreDeVariables++;
                }
     
                else if(tmp == NULL)
                printf("erreur\n");
     
        }
        return 0;
    }
    Voilà donc la fonction complète posant problème :/
    Je suis navré si je vous fait sauter au plafond devant ce code^^"

    Salutations,

    Neyort

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. allocation mémoire pour tableau de string
    Par alaninho dans le forum C++
    Réponses: 2
    Dernier message: 09/03/2012, 14h44
  2. Probleme de realloc pour un tableau 2D
    Par ptit_riton dans le forum Bibliothèque standard
    Réponses: 2
    Dernier message: 27/12/2008, 18h08
  3. Réponses: 11
    Dernier message: 26/09/2007, 21h24
  4. [Debutant]reallocation de memoire d'un tableau de type perso
    Par killerjeff dans le forum Débuter
    Réponses: 3
    Dernier message: 04/08/2004, 17h09
  5. Economie de mémoire pour plusieur images avec la même source
    Par neness dans le forum Composants VCL
    Réponses: 5
    Dernier message: 18/01/2004, 10h56

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