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 :

Tableaux dynamiques, fonctions, et gestion mémoire


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 13
    Points : 8
    Points
    8
    Par défaut Tableaux dynamiques, fonctions, et gestion mémoire
    Bonjour,

    J'ai un souci avec la gestion de la mémoire dans un de mes programmes.

    Sa structure est simple :

    Une fonction 1 traite des données, les intègre dans plusieurs tableaux dynamiques (méthode malloc) de dimension 300, et les envoie ensuite à une fonction 2 qui les traite à son tour, et si certaines conditions logiques renvoient FALSE, la fonction 2 renvoie ces données à la fonction 1 qui les retraite d'une certaine manière. Cela selon un rythme soutenu (> 100 toutes les 10 secondes).

    La mémoire s'envole et des erreurs apparaissent au niveau de ces tableaux dynamiques.

    Je suis extrêmement débutant (j'ai débuté C il y a une semaine), vos conseils me seront donc utiles.

    J'ai bien envie d'utiliser free(), mais je ne veux pas perdre ces données entre les deux fonctions. Mon impression est que ces tableaux dynamiques s'accroissent en mémoire alors que le nombre de données est le même.

    J'ai certainement fait une erreur de débutant, mais laquelle ?

    Merci !

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Voici quelques infos complémentaires.

    J'ai viré la quasi totalité des mallocs et les ai remplacés par des tableaux (je n'ai pas besoin de les redimensionner).

    Par ailleurs, ma fonction 1 modifie ces données à partir de rand(). J'ai déplacé srand((int)time(NULL)); dans le main() et ça a eu un petit effet positif, mais ce n'est clairement pas suffisant.

    Au lancement, j'ai une erreur de segmentation au bout de quelques secondes.

  3. #3
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 882
    Points
    7 882
    Par défaut
    Citation Envoyé par Hobbèse Voir le message
    J'ai certainement fait une erreur de débutant, mais laquelle ?
    Tu en a sûrement fait plusieurs, la première étant de penser que les lecteurs de ce forum ont des pouvoirs extra-lucides leur permettant de visualiser ton code ...
    ɹǝsn *sıɹɐlos*

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Fonction 1 appelle fonction 2 qui appelle fonction 1 qui appelle fonction 2 qui…. ? Ca s'arrête un jour ce cycle infernal ? Connais-tu le principe d'une pile (stack) et de l'erreur stack overflow ?

    D'un point de vue logique, je pense que tu devrais avoir fonction 1, fonction 2 et fonction 3 qui fait les contrôles et rappellent les fonctions appropriés en fonction des résultats.

    +1 pour jlliagre. La plupart des problèmes ont besoin d'un peu plus de détails, et souvent d'un code minimaliste reproduisant le problème.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Edit. Je viens de comprendre mon problème : je veux faire une récursivité profonde, même si non infinie. Je vais commencer mes recherches avec cet article : http://franckh.developpez.com/tutori...i/recursivite/ mais suis preneur de vos conseils.

    Je vous présente mes excuses. Il est évident qu'il m'était nécessaire de donner plus de détails.

    Les voici.

    L'effet souhaité :

    Manipuler aléatoirement le maximum de données par la fonction 1 afin d'être traitées par la fonction 2.

    Le code (ne riez pas trop, l'approche est extrêmement naïve : j'ai débuté il y a une semaine... Je l'ai simplifié en appellant la fonction 1 par elle-même) :

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
     
    #define DONNEES 36 // nombre de lignes dans le fichier
     
    void lancer(int *A, int *B, int *C, int *D, int *E);
     
    int main(int argc, char *argv[])
    {
        int *T = NULL;
        int A[DONNEES]={};
        int B[DONNEES]={};
        int C[DONNEES]={};
        int D[DONNEES]={};
        int E[DONNEES]={};
     
        srand((int)time(NULL));
     
        int i=0;
     
        T = malloc((DONNEES) * sizeof(int));
     
        FILE* fichier = NULL;
     
        fichier = fopen("test.txt", "r");
     
        char line[80];
        while ((fscanf(fichier, "%[^\n]", line)) != EOF)
        {
            fgetc(fichier);
            fscanf(fichier, "%d. %d %d %d %d", &T[0], &T[1], &T[2], &T[3], &T[4]);
     
            A[i] = T[0];
            B[i] = T[1];
            C[i] = T[2];
            D[i] = T[3];
            E[i] = T[4];
            i++;
        }
     
        lancer(A, B, C, D, E);
    }
     
    void lancer(int *A, int *B, int *C, int *D, int *E){
     
     
        int x=0, j;
        int Tab[5]={};
     
            for (x=0; x<DONNEES; x++)
            {
     
                j = rand()%DONNEES;
     
     
                Tab[0] = A[x];
                Tab[1] = B[x];
                Tab[2] = C[x];
                Tab[3] = D[x];
                Tab[4] = E[x];
     
                A[x] = A[j];
                B[x] = B[j];
                C[x] = C[j];
                D[x] = D[j];
                E[x] = E[j];
     
                A[j] = Tab[0];
                B[j] = Tab[1];
                C[j] = Tab[2];
                D[j] = Tab[3];
                E[j] = Tab[4];
     
                    printf("%d. %d %d %d %d\n", A[x], B[x], C[x], D[x], E[x]);
            }
     
     
        lancer(A, B, C, D, E);
    }
    Le résultat :

    Les données sont bien mélangées, mais apparaissent au bout de quelques seconde des données comme : 640 4096 352256 536904960 0

    Merci pour vos avis !

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    • Je ne vois pas de condition d'arrêt à ta fonction lancer()…
    • Tu lis une ligne mais tu n'en fais rien ?
    • Ta lecture des données est étonnante. A priori je pense que tu peux te passer de T. Peux-tu nous montrer un exemple du fichier de données ?
    • As-tu au moins tester lancer() avec des données codées en dur dans le main() ?
    • int A[DONNEES]={}; --> genre d'initialisation est interdite en C ISO. Mets plutôt {0}.
    • As-tu bien vérifié les valeurs prises par j ? Tu pourrais mettre un assert() pour t'assurer que tu ne quittes pas l'intervalle souhaité.



    PS : j'ai essayé un peu le code avec ça :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <assert.h>
     
    #define DONNEES 3 // nombre de lignes dans le fichier
     
    void lancer(int *A, int *B, int *C, int *D, int *E);
     
    int main(int argc, char *argv[])
    {
        int *T = NULL;
        int A[DONNEES]={0, 4, 7};
        int B[DONNEES]={0, 3, 8};
        int C[DONNEES]={0, 2, 9};
        int D[DONNEES]={0, 1, 5};
        int E[DONNEES]={0, 1, 8};
     
        srand((int)time(NULL));
     
        for(int i = 0; i < 20; i++) {
            puts("Lancer");
            lancer(A, B, C, D, E);
        }
    }
     
    void lancer(int *A, int *B, int *C, int *D, int *E){
     
     
        int x=0, j;
        int Tab[5]={0};
     
            for (x=0; x<DONNEES; x++)
            {
                j = rand()%DONNEES;
                assert(j < DONNEES && j >= 0);
     
                Tab[0] = A[x];
                Tab[1] = B[x];
                Tab[2] = C[x];
                Tab[3] = D[x];
                Tab[4] = E[x];
     
                A[x] = A[j];
                B[x] = B[j];
                C[x] = C[j];
                D[x] = D[j];
                E[x] = E[j];
     
                A[j] = Tab[0];
                B[j] = Tab[1];
                C[j] = Tab[2];
                D[j] = Tab[3];
                E[j] = Tab[4];
     
                printf("%d %d %d %d %d\n", A[x], B[x], C[x], D[x], E[x]);
            }
    }
    Si tu souhaites mélanger, un tableau, je pense que tu devrais faire une fonction mélange un tableau et appelle là sur chacun de tes tableaux. Le caractère aléatoire sera peut-être meilleur et aussi tu pourras travailler avec un nombre variable de tableaux et non 5.
    Enfin, je ne vois pas trop l'intérêt de la récursivité ici. Autant faire une boucle comme je l'ai fait dans le main(). Tu décides alors du nombre de fois où tu mélanges tes données.

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    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 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Hobbèse Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #define DONNEES 36 // nombre de lignes dans le fichier
     
    int main(int argc, char *argv[])
    {
        int *T = NULL;
        T = malloc((DONNEES) * sizeof(int));
        ...
    Bonjour

    malloc() ne se justifie que dans le cas où tu ne connais pas la taille de tes éléments.
    Ici tu la connais (36) donc pourquoi ne pas mettre directement int T[DONNEES] ???
    Accessoirement le vocable "DONNEES" n'est pas particulièrement parlant surtout quand tu dis qu'il s'agit d'un nombre de lignes (pourquoi ne pas l'appeler NB_LIG ?) et que tu t'en sers comme d'un nombre d'entiers !!!???!!!
    Commencer par identifier les éléments qu'on manipule et leur donner un nom adapté est déjà un quart de la réussite du programme...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut
    Attention réponse dangereuse donnée par un (autre) débutant qui veut progresser Vite

    1) Ligne 30 de ton fichier, le format de la ligne lue ne devrait il pas etre plutot "%[^/n]80" ?

    2) Toujours ligne 30 la condition que tu donnes a la boucle while me semble étrange...
    fscanf renvoie le nombre d arguments reconnus lors du scan, et tu le compares a EOF ?

    3) Enfin, effectivement , ta condition met une ligne (hors /n) dans ligne, mais finalement tu ne traites pas cette ligne dans ta boucle, au contraire, tu continues a parcourir ton fichier...

Discussions similaires

  1. Réponses: 3
    Dernier message: 16/03/2012, 10h30
  2. Réponses: 4
    Dernier message: 28/10/2010, 10h21
  3. [debutant nul] libération mémoire tableaux dynamiques
    Par hibiscuit dans le forum Débuter
    Réponses: 11
    Dernier message: 11/09/2007, 14h46
  4. [D7] Tableau dynamique et Gestion mémoire
    Par Cl@udius dans le forum Langage
    Réponses: 7
    Dernier message: 13/03/2006, 15h16
  5. fonction de gestion du temps
    Par fati dans le forum C
    Réponses: 5
    Dernier message: 26/12/2002, 16h32

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