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 :

Taille de tableau passe en parametre


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 48
    Par défaut Taille de tableau passe en parametre
    Bonjour,
    j'ai une fonction qui lit dans un fichier binaire et qui récupère les valeurs que j'y ai inscrit en les plaçant dans un tableau passé en paramètre.
    les valeurs sont des doubles.

    Mon problème porte sur la taille du tableau.

    Comment pourrai je tester sa taille pour reallouer la taille dynamiquement si nécéssaire.

    sachant que lorsque j'ai tester, j'ai pu acceder à l'indice 27 d'un tableau ne comportant que 8 case à la base... sans aucune erreur de la part ni du compilateur ni de linux.

    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
     
     
    int main(){
     
    	double reel[8];
    	envoieReels(pointeurSurFichier,reel)
    	}
     
    void envoieReels(FILE* fichier,double  reel[])
    {
     
     	double nb;
    	int retFread,i=0,j=0;
    	reel[27]=15;
    	/*le printf affiche effectivement 15.000000 alors que le tableau passé en paramètre fait 8 case*/
            printf("%f",reel[27]);
                while(1){
                        retFread=fread(&nb,sizeof(double),1,fichier);
                        if (feof(fichier)){/*sortie de boucle si EOF*/break;}
                        if (retFread!=1){printf("erreur lors de la lecture dans \"\"\n");exit(EXIT_FAILURE);}                 
                        if(j<=i){
                            reel[j]=nb;
                            j+=1;
                        }else{
                            printf("erreur, le tableau en argument est trop petit");
                            exit(EXIT_FAILURE);
                        }
                }
    }
    il existe probablement une solution, mais je ne comprend pas vraiment comment fonctionne l'accés a la mémoire du tableau.
    j'utilise gcc 4.4.1.

    Dans l'idéal, j'aimerai utiliser realloc pour eviter toute erreur de segmentation. sinon j'aimerai au moins pouvoir trouver la taille du tableau pour pouvoir quitter si le noimbre de valeur contenu dans le fichier est trop importante.

    Une dernière solution envisagé serai de crée le tableau dynamiquement sans le passé en paramètre et de renvoyer un poitneur sur double, mais je pense que ça risque de pas être très jolie de refaire un realloc a chaque nouveau nombre du fichier.


    D'avance merci...

    PS: comment mettre une signature de manière systématique ?

    Antoine DUBOIS
    License Informatique 2
    Université Claude Bernard Lyon 1

  2. #2
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    Par défaut
    bonsoir,

    sachant que lorsque j'ai tester, j'ai pu acceder à l'indice 27 d'un tableau ne comportant que 8 case à la base... sans aucune erreur de la part ni du compilateur ni de linux.
    Ce n'est pas parce qu'il n'y a rien qu'il n'y a pas d'erreur. Tu est tombé sur le pire cas possible, un depassement du tableau avec comportement indeterminé. Il aurait mieux value un SIGSEV.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	reel[27]=15;
    	/*le printf affiche effectivement 15.000000 alors que le tableau passé en paramètre fait 8 case*/
        printf("%f",reel[27]);
    Lors de l'affectation, tu as purement et simplement ecrasé une donné. Il pouvait s'agir d'une donné que tu utilise (et donc tu aura de drole de surprise plus tard) ou bien d'une donnée quelconque.
    Le, printf marche, car en faisant reel[27], c'est comme si tu faisait "reel + 27".
    Autrement dit, tu va a la premiere adresse de ton tableau, designé par reel, et tu va 27 adresse plus bas.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        if(j<=i)
        {
            reel[j]=nb;
            j+=1;
        }
        else
        {
            printf("erreur, le tableau en argument est trop petit");
            exit(EXIT_FAILURE);
        }
    Je suis un peu surpris. 'j' represente l'indice courant de ton tableau, et 'i' est censé represente la taille du tableau ? Seule probleme, si je ne m'abuse, i est initialise a 0 et ne bouge plus.

    Le mieux, si tu veux adapter ton tableau aux nombre exact de nombre de ton fichier serai de passer un pointeur sur double, puis de faire des realloc + 1 a chaque nombre lu. Ce n'est certe pas "sublime", mais je trouve cela suffisament jolie pour etre mis en oeuvre.

    Pour une chaine de caractere (char*, char[]), on peut connaitre sa longueur grace a strlen. Mais pour les tableau, pas de moyen autre que de passer la longueur via un int.

    Enfin, juste une chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
                while(1){
                        retFread=fread(&nb,sizeof(double),1,fichier);
                        if (feof(fichier)){/*sortie de boucle si EOF*/break;}
                        if (retFread!=1){printf("erreur lors de la lecture dans \"\"\n");exit(EXIT_FAILURE);}                 
                        if(j<=i){
                            reel[j]=nb;
                            j+=1;
                        }else{
                            printf("erreur, le tableau en argument est trop petit");
                            exit(EXIT_FAILURE);
                        }
    Cela n'est pour moi pas "jolie" du tout : un while(1), break histoire de sortir un jour quand meme, des EXIT_FAILURE ... bref, en allant sur la faq, tu trouverai certainement des idée pour ameliorer ca.

    Cordialement

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Pour jouer avec les tableaux et taille, j'ai tendance à faire ceci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct arrayList_double
    {
    	double* pTableau;
    	size_t capacite;
    	size_t taille;
    };
    Si l'on cherche à ajouter des données à un tableau dont la taille est égale à la capacité, on multiplie la capacité (un multiplicateur inférieur au nombre d'or est recommandé pour une raison mathématique que j'ai oubliée; J'utilise généralement 1.5 ou √2) et on réalloue.

    Citation Envoyé par wechteuf Voir le message
    PS: comment mettre une signature de manière systématique ?
    Il faut avoir au moins 50 messages hors-Taverne. Mais la signature n'apparaîtra que sur tes nouveaux messages, pas les anciens (à moins que tu les édites et coches la case "Afficher votre signature" qui sera alors visible).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    SofEvans :
    car en faisant reel[27], c'est comme si tu faisait "reel + 27".
    Cette manière de dire peut induire le lecteur en erreur.
    Plus exactement :

    " en faisant reel[27], c'est comme si tu faisait *(reel + 27) "

  5. #5
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 48
    Par défaut
    Mon code a des petite erreur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        if(j<=i)
        {
            reel[j]=nb;
            j+=1;
        }
        else
        {
            printf("erreur, le tableau en argument est trop petit");
            exit(EXIT_FAILURE);
        }
    c'est parce que j'ai essayer de tester la taille de mon tableau avec une méthode bidon et que j'ai pas modifier mon code au moment de le posteR
    i aurai du contenir le nombre de case du tableau.
    je vais donc m'essayer au realloc +1
    Une question cependant, dans le cas du realloc est ce que la variable doit nécéssairement été initialisé avec malloc ?

    quel est le problème avec mes exit(EXIT_FAILURE); ?
    je n'ai pas choisi ce comportement, ce sont mes profs qui ont choisi.

    Pour le while... je suis d'accord ça n'est pas très jolie, mais ça a le grand mérite de fonctionné... contraitrement à feof() auquel il faut rajouter des test pour obtenir le comportement adéquat.

    En tout cas merci pour vos petit précisions.

    Antoine DUBOIS
    License Informatique 2
    Université Claude Bernard Lyon 1


  6. #6
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 48
    Par défaut
    j'ai jamais aimé les structure en C...
    c'est drôlement pratique, mais en plus dans le cas présent. ça remet en cause une bonne partie de mon code.
    je penserai à cette solution la prochaine fois...


    Merci

  7. #7
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    Par défaut
    Citation Envoyé par wechteuf Voir le message
    quel est le problème avec mes exit(EXIT_FAILURE); ?
    je n'ai pas choisi ce comportement, ce sont mes profs qui ont choisi.

    Pour le while... je suis d'accord ça n'est pas très jolie, mais ça a le grand mérite de fonctionné... contraitrement à feof() auquel il faut rajouter des test pour obtenir le comportement adéquat.
    Désolé, c'est moi qui est dit ceci.
    C'est juste que je trouve cela un peu brutal, mais ca fonctionne. Le probleme va se poser si tu fais de l'allocation dynamique. Si tu reste comme ceci, tu va quitter sans liberer la memoire.
    Ce qui me gene vraiment, c'est while(1). Mais bon, comme tu dis, ca a le merite de fonctionner, tout les gouts sont dans la nature.

  8. #8
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 48
    Par défaut
    je n'avais pas pensé à la brutalité du procédé et surtout au problème de liberation de la mémoire.
    je vis devoir me pencher sur la question.

    En tout cas merci a tous pour vos réponse.

    Je vous tiens au courant de l'évolution de ce petit programme.

  9. #9
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Si l'on cherche à ajouter des données à un tableau dont la taille est égale à la capacité, on multiplie la capacité (un multiplicateur inférieur au nombre d'or est recommandé pour une raison mathématique que j'ai oubliée; J'utilise généralement 1.5 ou √2) et on réalloue.
    http://www.bourguet.org/v2/cs/realloc/
    Cordialement.

Discussions similaires

  1. Fonction recursive sur un tableau passé en parametre
    Par misterfed dans le forum Langage
    Réponses: 7
    Dernier message: 31/05/2012, 08h22
  2. PB Realloc avec pointeur sur tableau passé en parametre
    Par la_chevre dans le forum Débuter
    Réponses: 2
    Dernier message: 06/02/2009, 12h04
  3. tableau passe en parametre
    Par semaj_james dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 08/11/2006, 17h41
  4. Réponses: 32
    Dernier message: 24/07/2006, 19h19
  5. Réponses: 13
    Dernier message: 07/05/2006, 11h54

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