Tableaux à diverses dimensions avec diverses taille
leoliom
Messages postés
187
Statut
Membre
-
leoliom Messages postés 187 Statut Membre -
leoliom Messages postés 187 Statut Membre -
Bonjour,je veux créer non pas un tableau multidimensionnel mais un tableau du genre:
T=[[1,2,3],[4,1],[1,6,9,0,1]]
T est un tableau composé de 3 sous-tableaux avec chacun leur dimensions
le 1er sous tableau est de taille 3,le 2ieme est de taille 2 et le 3ieme de taille 5
Comment m'y prendre,créer un type qui permet de manipuler un tel type de tableau
Ensuite ,j'aimerais créer une fonction qui ajoute un sous-tableau dans T,une autre qui permet de supprimer un sous-tableau...
T=[[1,2,3],[4,1],[1,6,9,0,1]]
T est un tableau composé de 3 sous-tableaux avec chacun leur dimensions
le 1er sous tableau est de taille 3,le 2ieme est de taille 2 et le 3ieme de taille 5
Comment m'y prendre,créer un type qui permet de manipuler un tel type de tableau
Ensuite ,j'aimerais créer une fonction qui ajoute un sous-tableau dans T,une autre qui permet de supprimer un sous-tableau...
A voir également:
- Tableaux à diverses dimensions avec diverses taille
- Comment réduire la taille d'un fichier - Guide
- Appliquez à tous les paragraphes du document à télécharger, à l’exception des titres et des sous-titres, la mise en forme suivante : chaque paragraphe doit être espacé de 0,42 cm ou 12 pt du paragraphe qui suit les textes ne doivent pas être en retrait à droite et à gauche après ces modifications, sur quelle page se trouve le titre « la cheminée » dans le chapitre « informations diverses » ? - Guide
- Reduire taille image - Guide
- Afficher taille dossier windows - Guide
- Tableaux croisés dynamiques - Guide
26 réponses
Voici ce que j'ai fait pour éviter les fuites mémoires
temp = realloc (tabentier, 4 * sizeof(int) );
temp = realloc (tabentier, 4 * sizeof(int) );
tableau ajouter_entier(tableau t,int n){
int * temp;
if( t.taille==t.T_MAX){
temp=realloc(t.tab,2*sizeof(int));
if ( temp == NULL ){
printf("Reallocation impossible");
free(t);
}
}
t.taille=t.taille+1;
int dernier_indice=t.taille-1;
t.tab[dernier_indice]=n;
return t;
}
Si j'ai lu lma doc mais l'exemple je l'ai pas compris du coup j'ai regardé sur ce site mlà:https://rperrot.developpez.com/articles/c/allocationC/ au niveau du 2)Là il explique bien mieux les choses et j'ai appliqué le même principe mais apparemment c'est pas comme ca


Bref merci pour votre aide,je vais regardé plus de vidéo sur le C pour mieux comprendre
les choses
Merci d'avoir été patient avec moi
Bref merci pour votre aide,je vais regardé plus de vidéo sur le C pour mieux comprendre
les choses
Merci d'avoir été patient avec moi
tu vois donc bien que dans le 2ème bloc de code le contenu de temp, s'il ne contient pas NULL, est affecté à tabentier et que s'il contient NULL, l'erreur est gérée par une sortie du programme (ce qui est une des 3 issues que j'ai mentionnées).
Tu me postes donc ta source pour ton code mais on voit bien que tu ne l'appliquais pas.
je vais regardé plus de vidéo sur le C pour mieux comprendre
les choses
Je te le déconseille. Les vidéos sont peu pratiques, c'est une support linéaire qui te fait perdre du temps; dont la qualité est très variable.
Apprend à lire, comprendre et appliquer les documentations officielles des fonctions de la bibliothèque standard (pages de manuel sur Linux, sites https://www.cplusplus.com/reference/ ou https://en.cppreference.com/w/c et des supports de cours ou manuels dont la qualité est reconnue. Tu pourrais aussi investir quelques euros et acquérir :
Tu me postes donc ta source pour ton code mais on voit bien que tu ne l'appliquais pas.
je vais regardé plus de vidéo sur le C pour mieux comprendre
les choses
Je te le déconseille. Les vidéos sont peu pratiques, c'est une support linéaire qui te fait perdre du temps; dont la qualité est très variable.
Apprend à lire, comprendre et appliquer les documentations officielles des fonctions de la bibliothèque standard (pages de manuel sur Linux, sites https://www.cplusplus.com/reference/ ou https://en.cppreference.com/w/c et des supports de cours ou manuels dont la qualité est reconnue. Tu pourrais aussi investir quelques euros et acquérir :
- le K&R pour comprendre d'où vient le C et le style de programmation et conventions qui ont formé les programmeurs C depuis des lustres
- et un ouvrage récent prenant en compte les standards plus récents, comme : "21st Century C" de Ben Klemens et apprendre à utiliser des outils contemporains utilisés pour rendre la vie plus simple aux programmeurs C.
je veux pas vous fatigué ce sera ma dernière question et j'essayerais de faire le reste moi meme
Votre code là est trés interessant et j'ai tout compris,la partie là plus particuliérement:
Ici vous savez d'avance ce qu'il faut mettre1,2,3..
J'ai essayé de généraliser tous ca en faisant
compteur
Parcourir le tableau
mon_tableau[0]->taille =compteur
Dans mon code le compteur compte les éléments a mettre dans chaque tab et il marche j'ai vérifié
Aprés j'ai fait
Pour j allant de 0 au nombre de sous tableaux que je veux
Pour k allant de 0 au nombre d'elements que je veux dans mon tableau(donné par mon compteur)
mon_tableau[j]->tab[k] = T.tab[i];
Ca marche pas trés bien
CE que j'essaye de fairec'est si j'ai T=[1,2,3,4,5,-1,2,3] avoir:
mon_tableau[0]->taille = 5;
mon_tableau[0]->tab = malloc(sizeof(int) * 5);
mon_tableau[0]->tab[0] = T[0];
mon_tableau[0]->tab[0] = T[1];
mon_tableau[0]->tab[0] = T[2];
mon_tableau[0]->tab[0] = T[3];
mon_tableau[0]->tab[0] = T[4];
mon_tableau[0]->tab = malloc(sizeof(int) * 2);
mon_tableau[1]->tab = malloc(sizeof(int) * 2);
mon_tableau[0]->tab[1] = T[6];
mon_tableau[0]->tab[1] = T[7];
Ma derniere question et c'est fini pour mon sujet
#include <stdlib.h>
struct tableau {
int taille;
int *tab;
};
int main(void) {
int nb_de_sous_tableaux = 3;
struct tableau ** mon_tableau = malloc(sizeof(struct tableau *) * nb_de_sous_tableaux);
for (int i = 0; i < nb_de_sous_tableaux; i++) {
mon_tableau[i] = malloc(sizeof(struct tableau));
}
mon_tableau[0]->taille = 3;
mon_tableau[0]->tab = malloc(sizeof(int) * 3);
mon_tableau[0]->tab[0] = 1;
mon_tableau[0]->tab[1] = 2;
mon_tableau[0]->tab[2] = 3;
free(mon_tableau[0]->tab);
for (int i = 0; i < nb_de_sous_tableaux; i++) {
free(mon_tableau[i]);
}
free(mon_tableau);
return 0;
}
Votre code là est trés interessant et j'ai tout compris,la partie là plus particuliérement:
mon_tableau[0]->taille = 3;
mon_tableau[0]->tab = malloc(sizeof(int) * 3);
mon_tableau[0]->tab[0] = 1;
mon_tableau[0]->tab[1] = 2;
mon_tableau[0]->tab[2] = 3;
free(mon_tableau[0]->tab);
Ici vous savez d'avance ce qu'il faut mettre1,2,3..
J'ai essayé de généraliser tous ca en faisant
compteur
Parcourir le tableau
mon_tableau[0]->taille =compteur
Dans mon code le compteur compte les éléments a mettre dans chaque tab et il marche j'ai vérifié
Aprés j'ai fait
Pour j allant de 0 au nombre de sous tableaux que je veux
Pour k allant de 0 au nombre d'elements que je veux dans mon tableau(donné par mon compteur)
mon_tableau[j]->tab[k] = T.tab[i];
Ca marche pas trés bien
CE que j'essaye de fairec'est si j'ai T=[1,2,3,4,5,-1,2,3] avoir:
mon_tableau[0]->taille = 5;
mon_tableau[0]->tab = malloc(sizeof(int) * 5);
mon_tableau[0]->tab[0] = T[0];
mon_tableau[0]->tab[0] = T[1];
mon_tableau[0]->tab[0] = T[2];
mon_tableau[0]->tab[0] = T[3];
mon_tableau[0]->tab[0] = T[4];
mon_tableau[0]->tab = malloc(sizeof(int) * 2);
mon_tableau[1]->tab = malloc(sizeof(int) * 2);
mon_tableau[0]->tab[1] = T[6];
mon_tableau[0]->tab[1] = T[7];
Ma derniere question et c'est fini pour mon sujet
J'ai édité mon message où j'écrivais (j'ignore si tu l'as vu)
Ce code n'est prévu que pour des tableaux 2D où le nombre de colonnes pour chaque ligne est le même et est connu à l'avance.
(...)
car je me suis trompé, le code en question traite bien le cas de figure de sous-tableaux hétérogènes. Désolé pour cette confusion.
Je pense que sans ton code qui "généralise", je ne peux pas comprendre la nature exacte de ton problème.
Cependant, dans le principe, tu dois parcourir au préalable ton tableau fourni en entrée, pour déterminer dans un premier temps nb_de_sous_tableaux.
Ensuite, tu peux faire ton allocation de mon_tableau avec malloc().
Ensuite, tu dois parcourir, pour chaque sous tableau, ton tableau fourni en entrée, pour déterminer combien d'éléments chaque sous-tableau compte, et te servir de cette information pour fixer .taille et faire ton malloc() sur le pointeur .tab dans la struct
Ce code n'est prévu que pour des tableaux 2D où le nombre de colonnes pour chaque ligne est le même et est connu à l'avance.
(...)
car je me suis trompé, le code en question traite bien le cas de figure de sous-tableaux hétérogènes. Désolé pour cette confusion.
Je pense que sans ton code qui "généralise", je ne peux pas comprendre la nature exacte de ton problème.
Cependant, dans le principe, tu dois parcourir au préalable ton tableau fourni en entrée, pour déterminer dans un premier temps nb_de_sous_tableaux.
Ensuite, tu peux faire ton allocation de mon_tableau avec malloc().
Ensuite, tu dois parcourir, pour chaque sous tableau, ton tableau fourni en entrée, pour déterminer combien d'éléments chaque sous-tableau compte, et te servir de cette information pour fixer .taille et faire ton malloc() sur le pointeur .tab dans la struct
Avant de répondre a votre question ,j'ai remarqué que lorsque je veux tester votre realloc ca marche pas
Ca m'affiche Reallocation impossible : impossible d'ajouter un entier et s'arrete au 2ieme -1 au dela c'est impossible
Ca marche que a petite échelle
#include <stdio.h>
#include <stdlib.h>
typedef struct tableau {
int taille;
int *tab;
int T_MAX;
}tableau;
tableau creer_tab_vide(){
tableau t;
t.taille = 0;
t.T_MAX=10;
t.tab = malloc(10* sizeof(int));
return t;
}
tableau ajouter_entier(tableau t,int n){
int * temp;
size_t new_T_MAX = 2 * t.T_MAX * sizeof(int);
temp=realloc(t.tab, new_T_MAX);
if (temp == NULL) {
printf("Reallocation impossible : impossible d'ajouter un entier\n");
return t;
} else {
t.tab = temp;
t.T_MAX = new_T_MAX;
}
t.taille=t.taille+1;
int dernier_indice=t.taille-1;
t.tab[dernier_indice]=n;
return t;
}
void afficher_tableau(tableau T){
int i;
printf(" [");
for (i = 0; i < T.taille; i++){
printf("%d ",T.tab[i]);
}
printf("]\n");
}
int main(void){
tableau t;
t=creer_tab_vide();
t=ajouter_entier(t,1);
t=ajouter_entier(t,2);
t=ajouter_entier(t,3);
t=ajouter_entier(t,4);
t=ajouter_entier(t,-1);
t=ajouter_entier(t,6);
t=ajouter_entier(t,7);
t=ajouter_entier(t,8);
t=ajouter_entier(t,-1);
t=ajouter_entier(t,19);
afficher_tableau(t);
return 0;
}
Ca m'affiche Reallocation impossible : impossible d'ajouter un entier et s'arrete au 2ieme -1 au dela c'est impossible
Ca marche que a petite échelle
Mon code ici https://forums.commentcamarche.net/forum/affich-37585534-tableaux-a-diverses-dimensions-avec-diverses-taille?page=2#38 visait à te montrer comment utiliser realloc() dans la partie où tu décides d'augmenter la mémoire dans ton message immédiatement précédent https://forums.commentcamarche.net/forum/affich-37585534-tableaux-a-diverses-dimensions-avec-diverses-taille?page=2#37
je me suis concentré sur l'usage de realloc() pour bien t'expliquer son fonctionnement, pas sur le reste du code de la fonction.
Tu dois donc insérer ce code dans le tien, et non pas supprimer la partie de ton code où tu décides si tu as besoin de réallouer ou pas.
Là, dans ce que tu postes, tu doubles ma mémoire à chaque fois que tu ajoutes un élément (et non pas à chaque fois que tu va dépasser la capacité en éléments T_MAX).
je me suis concentré sur l'usage de realloc() pour bien t'expliquer son fonctionnement, pas sur le reste du code de la fonction.
Tu dois donc insérer ce code dans le tien, et non pas supprimer la partie de ton code où tu décides si tu as besoin de réallouer ou pas.
Là, dans ce que tu postes, tu doubles ma mémoire à chaque fois que tu ajoutes un élément (et non pas à chaque fois que tu va dépasser la capacité en éléments T_MAX).
Après tests, il y a bien un autre bogue, qui est dans le bout de code que j'ai posté et qui devrait être corrigé comme ceci :
car T_MAX contient le nombre d'éléments, pas leur taille occupée en mémoire. Cela permet au doublement d'aller moins vite et de se baser correctement sur le nombre d'éléments (lignes 1 et 2 modifiées ci-dessus).
N'oublie pas de mettre ceci dans ton
size_t new_T_MAX = 2 * t.T_MAX;
temp=realloc(t.tab, new_T_MAX * sizeof(int));
if (temp == NULL) {
printf("Reallocation impossible : impossible d'ajouter un entier\n");
return t;
} else {
t.tab = temp;
t.T_MAX = new_T_MAX;
}
car T_MAX contient le nombre d'éléments, pas leur taille occupée en mémoire. Cela permet au doublement d'aller moins vite et de se baser correctement sur le nombre d'éléments (lignes 1 et 2 modifiées ci-dessus).
N'oublie pas de mettre ceci dans ton
if( t.taille==t.T_MAX) { pour ne doubler que lorsque tu en as vraiment besoin.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Cela serait plutôt :
size_t new_T_MAX = 2 * t.T_MAX * sizeof(int) temp=realloc(t.tab, new_T_MAX); if (temp == NULL) { printf("Reallocation impossible : impossible d'ajouter un entier\n"); return t; } else { t.tab = temp; T.T_MAX = new_T_MAX; }Ce n'est très efficace, car "tableau" n'est, en fait, pas un tableau mais une struct, et lorsque celle-ci est passée en paramètre elle est copiée, et copiée de nouveau avec le return. En principe tu devrais passer un pointeur sur struct.
Enfin, c'est toi qui vois.
Encore une fois ces typedef ne servent à rien d'autre qu'à induire en erreur.
1.
ne modifie pas le pointeur passé en 1er paramètre dans la parenthèse car ce n'est pas ce que fait cette fonction selon la documentation : elle retourne le pointeur vers la zone mémoire redimensionnée. Il lui est impossible de modifier le pointeur passé en premier paramètre, car pour pouvoir le modifier, il lui faudrait l'adresse du pointeur, et le prototype ne le prévoit pas..
Tu dois donc affecter à si la réallocation a réussi.
2.
Si la réallocation a échoué, cela n'a aucun sens :
Le tout est assez décourageant, et c'est un euphémisme :-(
Si la réallocation échoue, cela signifie seulement que tu ne peux pas étendre la zone mémoire, mais la zone actuelle est toujours là et utilisable par le programme. En tant que concepteur du programme, tu peux décider ce qu'il va faire à ce moment face à cette erreur (à part afficher l'erreur). Par exemple :
Tu dois décider quoi faire et le faire. Pas libérer des trucs au hasard, ni permettre l'exécution de ta fonction alors que tu sais qu'elle n'est pas en mesure de s'exécuter correctement.
3.
Tu écrivais ci-dessus
Voici ce que j'ai fait pour éviter les fuites mémoires
temp = realloc (tabentier, 4 * sizeof(int) );
tableau ajouter_entier(tableau t,int n){
int * temp;
if( t.taille==t.T_MAX){
temp=realloc(t.tab,2*sizeof(int));
alors que dans https://forums.commentcamarche.net/forum/affich-37585534-tableaux-a-diverses-dimensions-avec-diverses-taille#34 tu écrivais :
finalement c'est bon probleme résolu j'ai modifié
t.tab=realloc(t.tab,2*t.T_MAX*sizeof(int));
La bonne taille est la 3ème, que j'ai mise dans le code corrigé. Ne me fait pas une 4ème ou 5ème version avec encore une taille différente dans un autre post, cela est fatiguant.
ou 4 fois, ne double pas la taille de ton tableau (qui peut en stocker 9 au début). Cela affecte 2 (ou 4 fois) la taille en octets occupée par un int en mémoire sur ta machine, c'est à dire de quoi stocker 2 ou 4 int et c'est tout. En somme tu réduis ta mémoire au premier appel à realloc() et ton programme va :
C'est tout, je crois, pour ce soir.