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 :

Besoin d'aide allocation dynamique


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 5
    Points : 4
    Points
    4
    Par défaut Besoin d'aide allocation dynamique
    Bonjour,

    Lors de la création d'un jeu j'ai eu besoin d'une matrice (tableau en 2 dimensions) et le fragment de code ci dessous marchais très bien:
    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
     
        int hauteurMatrice = 56, longueurMatrice = 100;
        int **matrice = NULL;
     
        matrice = malloc(hauteurMatrice * sizeof(int*));
        for (i = 0; i < hauteurMatrice; i++)
        {
            matrice[i] = malloc(longueurMatrice * sizeof(int));
        }
        for (i = 0; i < hauteurMatrice; i++)
        {
            for (j = 0; j < longueurMatrice; j++)
            {
                matrice[i][j] = CASE_VIDE;  //CASE_VIDE est un define qui vaux 0
            }
        }
    Ensuite j'ai voulu remplacer ce code par cette fonction:

    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
     
    void genererMatrice(int longueur, int hauteur, int **matrice)
    {
        int i, j;
     
        malloc(hauteur * sizeof(int*));
        for (i = 0; i < hauteur; i++)
        {
            matrice[i] = malloc(longueur * sizeof(int));
        }
        for (i = 0; i < hauteur; i++)
        {
            for (j = 0; j < longueur; j++)
            {
                matrice[i][j] = CASE_VIDE;
            }
        }
        return;
    }
    Et je l'ai appelé dans mon code principal par la ligne suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    genererMatrice(longueurMatrice, hauteurMatrice, matrice);
    Avant de remplacer le code par la fonction tout marchais très bien mais maintenant ça ne marche plus le programme (en SDL) se ferme instantanément et codeblock ne m'affiche aucun message d'erreur je ne voie pas ou j'ai pu commettre une erreur dans ce code, si vous pouviez m'aider je vous en serais reconnaissant...

    Je précise que je suis forcé d'utiliser l'allocation dynamique car la matrice générée dépend en fait de la taille de l'écran.

  2. #2
    Membre expérimenté

    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2009
    Messages
    553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2009
    Messages : 553
    Points : 1 672
    Points
    1 672
    Par défaut
    Hello,

    Y'a comme un problème à cette ligne là:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        malloc(hauteur * sizeof(int*));

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    explique toi ^^

  4. #4
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    malloc retourne un pointeur sur la mémoire allouée. Qu'as-tu fait de ce pointeur? rien, tu l'as laissé filer dans l'hyper-espace. Et maintenant tu te demandes pourquoi ton programme s'exécute dans une faille spatio-temporelle...
    Comme on fait son lit, on se couche.

  5. #5
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    De plus, attention à passer le paramètre matrice par référence et non par valeur lors de l'appel.

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    Bien vu pour:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    malloc(hauteur * sizeof(int*));
    du coup j'ai remplacé cette ligne par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    matrice = malloc(hauteur * sizeof(int*));
    mais ça ne marche toujours pas...
    Aussi qu'est ce que tu voulais dire Matt_Houston par "passer le paramètre matrice par référence et non par valeur lors de l'appel" je ne comprend pas le sens de cette phrase ^^ dsl je ne suis qu'un débutant

  7. #7
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Si la fonction est conçue pour modifier une variable à portée extérieure de type mettons T (ici int **), alors il faut lui passer l'adresse de cette variable soit un T * (ici int ***) à l'aide de l'opérateur &. C'est une erreur qui ressort régulièrement des sujets ouverts par les débutants.

  8. #8
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    mais je genere une matrice de type int** et la fonction demande un type int** donc pas besoin de lui envoyer l'adresse puisque c'est deja un double pointeur, si j'envoie &matrice a la fonction elle va recevoir un type int***

  9. #9
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    mais je genere une matrice de type int** et la fonction demande un type int** donc pas besoin de lui envoyer l'adresse puisque c'est deja un double pointeur, si j'envoie &matrice a la fonction elle va recevoir un type int***
    Justement, comme cela se passe dans une fonction, il faut un degré d'indirection supplémentaire.
    Ce qui se passe pour l'instant, c'est:
    1) le pointeur matrice, de type int**, est copié comme tout argument lors de l'appel de la fonction
    2) la copie locale de ce pointeur prend comme valeur le retour de malloc (donc copie != original)
    3) à la sortie de la fonction cette copie est perdue (c'est une variable locale)
    4) le pointeur matrice originel a conservé sa valeur initiale

    Donc, il faut modifier la signature de la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void genererMatrice(int longueur, int hauteur, int ***matrice);
    Et au sein de la fonction affecter la valeur de retour de malloc à l'adresse sur laquelle pointe matrice:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *matrice = malloc(l*sizeof(int));
    Tu peux appeler la fonction par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    genererMatrice(l, c, &matrice);
    Là normalement tout se passera bien: c'est l'adresse de matrice qui est copiée et à cette adresse qu'on affecte la valeur retour de malloc.

  10. #10
    Membre expérimenté

    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2009
    Messages
    553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2009
    Messages : 553
    Points : 1 672
    Points
    1 672
    Par défaut
    Cela dit, pour le coup, est-ce que ce ne serait pas plus logique de faire une fonction de la forme suivante ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int ** genererMatrice(int longueur, int hauteur)

  11. #11
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    « Logique » je ne sais pas, car les deux constructions sont viables même si ta proposition est aussi ce que je choisirais nnovic. « Historiquement fidèle », oui sans doute car au final il s'agit d'une fonction d'allocation et il est naturel qu'elle imite la construction de *alloc.

  12. #12
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Je pense aussi que c'est la signature à préférer quand on n'a pas besoin de la valeur de retour pour autre chose, par exemple un code d'erreur différencié. En l'occurrence, renvoyer NULL en cas d'échec de l'allocation mémoire suffit à connaître le problème rencontré. Mais la fonction pourrait aussi valider la taille de la matrice ou je ne sais quoi.

  13. #13
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    Ha oui effectivement la fonction ne peut pas agir sur ma matrice car elle créé une autre variable de type matrice et recupere l'adresse dedans et enfin ma matrice meurt !
    Du coup j'ai fait comme ça et ça marche:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int **matrice = genererMatrice(longueurMatrice, hauteurMatrice);
    et voici la fonction genererMatrice:
    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** genererMatrice(int longueur, int hauteur)
    {
        int i, j;
        int **matrice = NULL;
     
        matrice = malloc(hauteur * sizeof(int*));
        for (i = 0; i < hauteur; i++)
        {
            matrice[i] = malloc(longueur * sizeof(int));
        }
        for (i = 0; i < hauteur; i++)
        {
            for (j = 0; j < longueur; j++)
            {
                matrice[i][j] = CASE_VIDE;
            }
        }
        return matrice;
    }
    Sujet résolu merci les gars pour votre aide

  14. #14
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    C'est bien mais n'oublie pas la gestion d'erreur : malloc peut échouer.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Aide allocation dynamique
    Par lassault1 dans le forum Débuter
    Réponses: 8
    Dernier message: 23/04/2010, 20h05
  2. Besoin d'aide sur les Graphiques dynamiques
    Par Didosaure dans le forum 2D
    Réponses: 0
    Dernier message: 21/04/2010, 01h46
  3. [AJAX] Image Dynamique en AJAX et servlet JAVA
    Par Canary3d dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 29/02/2008, 12h04
  4. Besoin d'aide pour les structures de données dynamiques
    Par aurelie689 dans le forum Pascal
    Réponses: 3
    Dernier message: 26/12/2007, 21h29
  5. besoin d'aide sur tableau dynamique
    Par littlesquall dans le forum C
    Réponses: 16
    Dernier message: 02/11/2005, 02h50

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