Partage
  • Partager sur Facebook
  • Partager sur Twitter

Allocation dynamique 2D

8 septembre 2018 à 12:00:25

Salut, je maîtrise depuis un moment l'allocation dynamique

p=(int *) malloc (taille * sizeof(int));

Le problème maintenant c'est que j'aimerai faire la même chose en 2 dimensions, normalement pour déclarer un tableau à deux dimensions on a besoin que de deux variables (nColonnes & nLignes) mais sur le net je n'ai pas trouvé une fonction simple comme l'allocation à une dimension pourtant ça me semble très basique.

La seule solution que j'ai pu utilisé c'est de compter le nombre de cases=nLigne*nColonnes et de faire un tableau à une dimension puis j'ai ajouté une fonction qui manipule le tableau comme s'il était en 2D.

  • Partager sur Facebook
  • Partager sur Twitter
"C'est un coup du sort étrange : tout les hommes dont on a ouvert le crâne avaient un cerveau" . Wittgenstein.
8 septembre 2018 à 12:20:47

Lu'!

Il ne faut pas utiliser malloc/free en C++ à moins d'avoir une raison absolument excellente de le faire (ce qui n'arrive quasiment jamais et franchement pas dans le cadre de projets de débutants). Il ne faut d'ailleurs pas utiliser new et delete non plus. Pour le même raison.

Donc déjà de base : std::vector.

Ensuite, on peut constater qu'un tableau à deux dimensions, c'est juste un tableau à une dimension de taille largeur*hauteur. Et que pour se déplacer à une case (x,y), on a juste à se déplacer à la case (y*largeur + x).

Un exemple d'implémentation : https://openclassrooms.com/forum/sujet/tableau-multi-dimensionnel-dynamique-et-affichage#message-87885328 .

PS : tu ne maîtrises pas l'allocation dynamique manuelle de ressource en C++. C++ est un langage à exceptions. Il est tout bonnement impossible de manipuler de l'allocation dynamique manuelle dans ce cadre sans écrire du code plein de fuites.

-
Edité par Ksass`Peuk 8 septembre 2018 à 12:22:00

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

8 septembre 2018 à 12:40:41

Ksass`Peuk a écrit:

Lu'!

Il ne faut pas utiliser malloc/free en C++ à moins d'avoir une raison absolument excellente de le faire (ce qui n'arrive quasiment jamais et franchement pas dans le cadre de projets de débutants). Il ne faut d'ailleurs pas utiliser new et delete non plus. Pour le même raison.

Donc déjà de base : std::vector.

Ensuite, on peut constater qu'un tableau à deux dimensions, c'est juste un tableau à une dimension de taille largeur*hauteur. Et que pour se déplacer à une case (x,y), on a juste à se déplacer à la case (y*largeur + x).

Un exemple d'implémentation : https://openclassrooms.com/forum/sujet/tableau-multi-dimensionnel-dynamique-et-affichage#message-87885328 .

PS : tu ne maîtrises pas l'allocation dynamique manuelle de ressource en C++. C++ est un langage à exceptions. Il est tout bonnement impossible de manipuler de l'allocation dynamique manuelle dans ce cadre sans écrire du code plein de fuites.

-
Edité par Ksass`Peuk il y a 9 minutes


Je ne connais pas encore les notions de classe, vecteur... mais je pense que cette solution est plus facile (elle ressemble à ce que tu as dit)

void case_2d(int x, int y, int d1, int value, int *p) //d1 est la largeur
{
    *(p+x+y*d1)=value;
}


Il suffit d'ajouter des conditions pour ne pas sortir de la grille, je peux faire du 3D avec cette méthode mais ça fait vite mal à la tête, l'avantage c'est que je peux choisir mon propre point de départ pour chaque dimension :)

  • Partager sur Facebook
  • Partager sur Twitter
"C'est un coup du sort étrange : tout les hommes dont on a ouvert le crâne avaient un cerveau" . Wittgenstein.
8 septembre 2018 à 13:24:15

"Non, non, non plus rapide, plus facile, plus séduisant." -- un grand dev C++.

Ta solution est pas du tout plus facile. Elle comporte des pieges que tu ne réalises probablement pas si tu débutes en C++. 

Il est tentant quand on debute de vouloir bosser sur ses propres projets, mais tu devrais apprendre des bases solides avant de te lancer dans des choses trop complexes.

  • Partager sur Facebook
  • Partager sur Twitter
8 septembre 2018 à 13:35:47

Vertinhol a écrit:

Je ne connais pas encore les notions de classe, vecteur... mais je pense que cette solution est plus facile

Tu as tort.

A moins que tu saches où est la fuite de mémoire dans ce code :

int * p = malloc(sizeof(int));
std::cout<<"lol"<<std::endl;
free(p);

-
Edité par Ksass`Peuk 8 septembre 2018 à 17:31:36

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

8 septembre 2018 à 18:37:26

Ksass`Peuk a écrit:

Vertinhol a écrit:

Je ne connais pas encore les notions de classe, vecteur... mais je pense que cette solution est plus facile

Tu as tort.

A moins que tu saches où est la fuite de mémoire dans ce code :

int * p = malloc(sizeof(int));
std::cout<<"lol"<<std::endl;
free(p);

-
Edité par Ksass`Peuk il y a environ 1 heure


Je pense que tu n'as pas déclaré la taille

int * p=(int*) malloc(taille * sizeof(int));

(taille = nLignes*nColonnes)

  • Partager sur Facebook
  • Partager sur Twitter
"C'est un coup du sort étrange : tout les hommes dont on a ouvert le crâne avaient un cerveau" . Wittgenstein.
8 septembre 2018 à 18:43:36

Pour le coup tu dis n'importe quoi.

dans ce cas là on alloue juste un seul int, donc ta taille vaut "1". Mais cela ne répond pas à la question de Ksass : Pourquoi ce code est il bugué.

  • Partager sur Facebook
  • Partager sur Twitter
http://cpp-rendering.io : Vous trouverez tout ce dont vous avez besoin sur Vulkan / OpenGL et le rendu 3D !
8 septembre 2018 à 18:57:24

Qnope a écrit:

Pour le coup tu dis n'importe quoi.

dans ce cas là on alloue juste un seul int, donc ta taille vaut "1". Mais cela ne répond pas à la question de Ksass : Pourquoi ce code est il bugué.


Bah, pour moi le syntaxe est incomplet et pour le compilateur il s'agit d'une erreur de conversion.

int* Allocate_grid(int d)
{
    int *p;
    p=(int*) malloc(d * sizeof(int));
    return(p);
}

void Put_value(int *p, int d, int d1, int x, int y, int value)
{
    *(p+x+y*d1)=value;
}

void Display_value(int *p, int d, int d1, int x, int y)
{
    cout<<"La valeur de la case ("<<x<<","<<y<<") est: "<<*(p+x+y*d1);
}

int main()
{
    int d1, d2, d, *p;
    cout << "Donner la taille de la premiere dimension: ";
    cin >> d1;
    cout << "Donner la taille de la deuxieme dimension: ";
    cin >> d2;
    d=d1*d2;
    p=Allocate_grid(d);
    Put_value(p,d,d1,0,1,59);
    Display_value(p,d,d1,0,1);
    return 0;
}

Voici ce que j'ai fait, ça marche parfaitement mais malheureusement je ne vois pas encore les pièges :/ .

-
Edité par Vertinhol 8 septembre 2018 à 18:58:04

  • Partager sur Facebook
  • Partager sur Twitter
"C'est un coup du sort étrange : tout les hommes dont on a ouvert le crâne avaient un cerveau" . Wittgenstein.
8 septembre 2018 à 19:21:19

Ok, il faut préciser peut etre comment on fonctionne sur le forum, pour pas que tu le prennes pour une attaque personnelle.

Beaucoup de gens qui viennent poser des questions sont débutants et donc on fait particulièrement attention a la qualité du code et aux détails. Parce que c'est tres important pour progresser en C++.

Quand ksass te pose cette question, c'est pour voir si tu connais les problèmatiques liées a l'utilisation de code C en C++. Savoir si tu sais pourquoi le code qu'il a donné peut produire des fuites mémoire, et donc surtout savoir si tu sais comment éviter ces fuites mémoires.

Si tu ne sais pas cela, on va forcement t'orienter sur du code qui sera valide, sans fuite mémoire. 

Un "ça marche" n'est pas du tout satisfaisant pour savoir si un code est valide.

Et en fait, même en C, ton dernier code n'est pas valide. Tu fais un malloc sans faire de free.

Donc il faut que tu utilises std::vector. Quand tu auras progressé dans ton apprentissage, tu pourras aborder les syntaxes plus bas niveau, mais a ce niveau, c'est casse gueule.

  • Partager sur Facebook
  • Partager sur Twitter
8 septembre 2018 à 20:00:41

Qnope a écrit:

Mais cela ne répond pas à la question de Ksass : Pourquoi ce code est il bugué.


a- Quid si une exception est lancée depuis operator<<?

b- Si j'en crois https://gist.github.com/shafik/848ae25ee209f698763cffee272a58f8#subtle-differences, accéder à une zone allouée par malloc pour un mettre un POD sans passer par un placement new serait une UB en C++ (17?) Je n'ai pas encore vérifié l'info à 100%

  • Partager sur Facebook
  • Partager sur Twitter
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
8 septembre 2018 à 22:57:33

D'après ce que j'ai compris il suffit d'ajouter free(p) à la fin du main
  • Partager sur Facebook
  • Partager sur Twitter
"C'est un coup du sort étrange : tout les hommes dont on a ouvert le crâne avaient un cerveau" . Wittgenstein.
8 septembre 2018 à 22:58:48

En C, oui. En C++, avec les excpetions, ce n'est pas suffisant.
  • Partager sur Facebook
  • Partager sur Twitter
8 septembre 2018 à 22:59:01

Ca ne suffit plus, tu es ici en C++.
  • Partager sur Facebook
  • Partager sur Twitter
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
8 septembre 2018 à 22:59:04

lmghs : Oui, mais le but c'était que le PO réponde ;).

  • Partager sur Facebook
  • Partager sur Twitter
http://cpp-rendering.io : Vous trouverez tout ce dont vous avez besoin sur Vulkan / OpenGL et le rendu 3D !
8 septembre 2018 à 23:12:08

C'est quoi le PO xD et je ne sais pas comment je peux intégrer le mot "new" dans l'allocation de mon code pour que ça devient digérable par le compilateur, j'ai essayé de le placer dans différent endroit mais ça n'a pas marcher :)

int* Allocate_grid(int d)
{
    int *p=(int*) malloc(d * sizeof(int));
    return(p);
}



  • Partager sur Facebook
  • Partager sur Twitter
"C'est un coup du sort étrange : tout les hommes dont on a ouvert le crâne avaient un cerveau" . Wittgenstein.
8 septembre 2018 à 23:19:32

N'utilises pas new non plus. Utilises std::vector.

Il est bien sur possible d'utiliser malloc et new en C++, mais pour le faire correctement, c'est un peu compliqué. Cf par exemple ce papier : http://www.stroustrup.com/except.pdf Il faut en fait utiliser une technique qui s'appelle le RAII. Il est beaucoup plus simple d'apprendre dans un premier temps à utiliser std::vector que gérer les exceptions.

  • Partager sur Facebook
  • Partager sur Twitter
8 septembre 2018 à 23:26:32

gbdivers a écrit:

N'utilises pas new non plus. Utilises std::vector.

Il est bien sur possible d'utiliser malloc et new en C++, mais pour le faire correctement, c'est un peu compliqué. Cf par exemple ce papier : http://www.stroustrup.com/except.pdf Il faut en fait utiliser une technique qui s'appelle le RAII. Il est beaucoup plus simple d'apprendre dans un premier temps à utiliser std::vector que gérer les exceptions.


J'ai déjà commencé à faire des fonctions qui calcule la somme des lignes, colonnes, diagonales...Dommage faut que je change de méthode, bon je vous remercie pour l'aide :)
  • Partager sur Facebook
  • Partager sur Twitter
"C'est un coup du sort étrange : tout les hommes dont on a ouvert le crâne avaient un cerveau" . Wittgenstein.
8 septembre 2018 à 23:30:38

Bonne nouvelle pour toi ! C'est l'occasion d'apprendre a ecrire correctement ce code ! Tu as de la chance !
  • Partager sur Facebook
  • Partager sur Twitter
8 septembre 2018 à 23:58:39

J'arrive après la guerre et j'en profite pour faire un peu de pub pour mon devblog sur lequel se trouve un article qui répond très exactement à cette problématique : https://sirlynixvanfrietjes.be/2018/05/23/c-moderne-la-gestion-de-la-memoire/

Bisous

  • Partager sur Facebook
  • Partager sur Twitter

Mes articles | Nazara Engine | Discord NaN | Ma chaîne Twitch (programmation)