Bonjour,
j'ai une matrice a[m][n] , quand je fais (int*)a , qu'est ce qui se passe?
merci
Version imprimable
Bonjour,
j'ai une matrice a[m][n] , quand je fais (int*)a , qu'est ce qui se passe?
merci
Tu te retrouve avec un tableau de pointeur.
Autrement dit pas du tout ce que tu veux faire.
pour ce que tu veux faire c'est un truc du genre :
Voila j'ai pas test mais normalement ca fonctionne :)Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 int* tab = new int[m * n + 1]; int total_index = 0; for (int i = 0; i < m; ++i) { for (int ibis = 0; ibis < n; ++ibis) { tab[total_index] = a[i][ibis]; ++total_index; } } tab[total_index] = NULL;
Ceci dit je te conseil de faire un objet qui gere automatiquement tes tableaux et de reviser les pointeurs :p
non non non c'est pas un tableau de pointeurs, c'est un tableau de tableaux
a[m][n] est représenté contigu en mémoire et si on le transforme en (int*) alors on obtient les lignes ou les colonnes a la suite les unes des autres (j'ai jamais su si c'etait les lignes ou les colonnes, quelqu'un de plus calé pourra te dire)
je crois que c'est les lignes a la suite les unes des autres
si m=n=2, et que la matrice a vaut a = { { 0, 1 }, { 2, 3 } }
alors si on caste a en int* : b = (int*)a alors b sera un tablea de 4 éléments
b = { 0, 1, 2, 3 }
si t'as un int** tu as un tableau de pointeur, chaque pointeur dans ce tableau pointant alors sur un tableau.
la valeur de tab est un poiteur (pointant sur la premiere case d'un tableau de pointeur)Code:
1
2
3
4
5
6
7
8
9 int** tab; (tab)--->(tab[0], tab[1], tab[2] ...) | | | V V V (tab[0][0]) (tab[1][0]) (tab[2][0]) (tab[0][1]) (tab[1][1]) (tab[2][1]) (tab[0][2]) (tab[1][2]) (tab[2][2])
la valeur de tab[n] est un pointeur (pointant sur la premiere case d'un tableau d'int)
la baleur de tab[n][m] est un int
Donc caster un int** en in int* revient a avoir un tableau de pointeur !
Autrement dit c'est totalement inutile !
a[m][n] est un tableau de tableau ici, pas un tableau de pointeurs
moi je l'ai compris comme
et dans ce cas tab2d est un tableau de tableaux, pas un tableau de pointeursCode:
1
2 int tab2d[2][2]; int* tab1d = (int*)tab2d;
Oui mais il demandait si ce qu'il recuperait si il avait fasait ca :
Moi j'appelle (tab1d) un tableau de pointeur vu que c'etait des pointeurs a l'origine.Code:
1
2 int* tab1d = (int*)tab2d;
Ceci etant ils sont utilises comme des ints a cause du cast. On peut donc dire que tab1d est un tableau d'int (qui ont pour valeur des addresses).
Enfin de toutes facons c'est un cast qui rime a rien ...
Pour faire un tableau 1d a partir d'un tableau 2d il faut faire une copie des valeurs dans un nouveau tableau (comme dans mon premier post).
je vous explique :
j'ai une classe MatriceCreux dont l'un des attributs est int *P (c'est donc un pointeur sur entier) . une des methodes de la classe Matrice est modifierpointeur dont le corps est :
cette methode appliquée à un objet MatriceCreux , fait pointer l'attribut P de cette MatriceCreux sur l'entier passé en argument.Code:
1
2
3
4 void MatriceCreux::modifierpointeur(int *b) { P=b; }
dans une autre méthode de la classe qui prend entre autre en argument un objet MatriceCreux M,j'ai initialisé une matrice a[n][m] , puis j'ai fait mon boutot .. juste avant la fin de cette classe ,j'ai fait
donc desormais le pointeur de M va pointer sur un tableau uniligne de taille n*m .Code:M.modifierpointeur((int *)a);
dites moi s'il vous plait ,si mon raisonnement est juste .merci
NON! pinaiseCitation:
Enfin de toutes facons c'est un cast qui rime a rien ...
Pour faire un tableau 1d a partir d'un tableau 2d il faut faire une copie des valeurs dans un nouveau tableau (comme dans mon premier post).
ca dépend du tableau 2d de depart mais si c'est une matrice genre int a[2][2] alors on peut le caster en tableau 1d et les valeurs seront contigues
oui oui ,lamatrice au debut est
a[100][3] . et donc là ca marche ??
le pointeur P va pointer sur le premier element de ce tableau?
oui, la il y a 300 entiers cote a cote dans le tableau, je ne sais plus dans quel ordre exactement (je confond toujours) mais ils sont cote a cote en memoire
Dans tout les cas les cast C-like c'est moche et a bannir..
Ok on s'est pas compis je partais pas sur le principe que sa matrice n'etait pas de taille fixe mais te taille varriable.
Si l'alocation est fixe :
Alors oui le cast fonctionnera (j'ai lu ton dernier message un peu vite :lol:).Code:
1
2 int tab_2d[2][2];
En revanche si le tableau est de taille varriable et que l'allocation est du genre:
http://tof.canardpc.com/view/9b31236...8d90d4e885.jpg
Comme le montre le debug il se retrouve bien avec un tableau contenant la valeurs des pointeurs ...
C'est pour ca que je lui conseillait de faire objet permetant de simuler un tableau 2d avec un tableau 1d (comme le fait le C++ avec la declaration "int tab[2][2]"). Histoire d'eviter quelques news.
Avec un tableau 2D alloué dynamiquement de cette manière, ça marche aussi (vu que c'est la conversion inverse qui est faite pour remplir le tableau de pointeurs).
Et bien sûr, les casts C-style sont à éviter. Pour la conversion int[2][2] vers int*, je conseillerais plutôt un reinterpret_cast, ou tout simplement un &tab2d[0][0].
Excuse moi mais je ne vois pas la difference entre la methode que je montre sur le screen de VS.
Mise a part le fait que ce soir du C il y a quand meme une allocation pour l'index et une allocation pour chaque ligne !
Ma méthode ne fait pas une allocation pour chaque ligne, elle les alloue toutes d'un seul coup.
- Le screen de VS fait 1+n allocations:
- 1 allocation de n,
- n allocations de m.
- Ma méthode fait 2 allocations:
- 1 allocation de n,
- 1 allocation de n*m.
Ha oui :p
Encore une fois j'ai lu trop vite :roll:
Et effectivement en c'est une tres bonne methode (que j'ai deja utilise) mais un peu plus compliquee que celle consistant a faire un malloc par ligne.
Sinon pour pousser un peu tu as essaye de le faire en 1 seul malloc ?
En theorie ca devrait etre possible avec quelques casts.
Par contre avec ces methods il faut faire attention aux overflows. Valgrind ne dira rien en cas de debordement :pCode:
1
2
3
4
5
6 malloc(sizeof(ptr1) * 3 + sizeof(data) * 2); ------------------v [ptr][ptr][NULL][data][data] -----------------^
Je testerais peut etre si j'ai le temps.
Et aussi faire attention aux contraintes d'alignement, je pense.
J'ai l'impression que si on prend en compte la gestion d'erreurs, c'est plus simple en fait. Dans la version "un malloc par ligne", si l'allocation d'une ligne échoue, il faut désallouer toutes les autres avant de désallouer les pointeurs.Citation:
un peu plus compliquee que celle consistant a faire un malloc par ligne