Malloc
Fermé
judy-brainy
Messages postés
15
Date d'inscription
samedi 17 avril 2010
Statut
Membre
Dernière intervention
29 décembre 2010
-
17 avril 2010 à 19:33
judy-brainy Messages postés 15 Date d'inscription samedi 17 avril 2010 Statut Membre Dernière intervention 29 décembre 2010 - 19 avril 2010 à 18:40
judy-brainy Messages postés 15 Date d'inscription samedi 17 avril 2010 Statut Membre Dernière intervention 29 décembre 2010 - 19 avril 2010 à 18:40
3 réponses
Pacorabanix
Messages postés
3248
Date d'inscription
jeudi 23 août 2007
Statut
Membre
Dernière intervention
19 mai 2013
662
Modifié par Pacorabanix le 18/04/2010 à 22:14
Modifié par Pacorabanix le 18/04/2010 à 22:14
ok je crois que je comprends ton souci.
alors bien évidemment tu dois faire un malloc pour la structure elle-même. malloc(sizeof(LIST) ou un truc du genre.
[EDIT après commentaire ci-dessous] Elle contient une variable tableau. un tableau en C c'est presque comme un pointeur vers le premier élément.
tu devrais pouvoir faire ainsi : déclarer int t* pour ton tableau et ensuite :
j'ai peut-être fait une ou deux fautes, je n'ai pas testé le code.
alors bien évidemment tu dois faire un malloc pour la structure elle-même. malloc(sizeof(LIST) ou un truc du genre.
[EDIT après commentaire ci-dessous] Elle contient une variable tableau. un tableau en C c'est presque comme un pointeur vers le premier élément.
tu devrais pouvoir faire ainsi : déclarer int t* pour ton tableau et ensuite :
//allocation pour la structure l = malloc(sizeof(LIST)); if ( l != null ) { /*on alloue le tableau */ /*tu peux demander le n ici, comme ça tu pourras allouer la taille que tu veux directement ou alors simplement allouer 20 cases. */ l.t = malloc(l.n*sizeof(int)); /* reste du programme ... */ } else printf("Erreur");
j'ai peut-être fait une ou deux fautes, je n'ai pas testé le code.
tatou_38
Messages postés
1928
Date d'inscription
vendredi 21 avril 2006
Statut
Membre
Dernière intervention
5 août 2015
121
17 avril 2010 à 20:05
17 avril 2010 à 20:05
Il y a aussi un autre problème fatal :
void main()
{
LIST *l;
int i;
int val;
printf("n=");
scanf("%d",&l->n);
Tu as déclaré l comme étant un pointeur sur une structure de type LIST. Pourquoi pas.
Tu utilises ce pointeur l pour y ranger la valeur lue par scanf().
Problème sur quoi pointe l ??? Et bien sur rien car l n'est pas initialisé, autrement dit le scanf() va mettre la valeur saisie quelque part dans la mémoire, pourquoi pas à une adresse qui va tout faire planter, ou qui va corrompre des données.
TU NE PEUX PAS UTILISER DE POINTEURS NON INITIALISE !!!
il faut par exemple que tu ajoutes avant le scanf() :
l = malloc(sizeof(LIST));
if (!l) { gestion d'erreur }
Maintenant l pointe bien sur une zone mémoire correctement définie.
N'oublie pas de désallouer l une fois devenu inutile ( free(l) );
Je n'ai pas été plus loin dans ton code.
Un truc : Utilise la notation hongroise pour bâtir tes noms de variable :
sNombre ==> variable de type short
usNombre ==> variable de type unsigned short
lNombre ==> variable sur un long
etc ...
psNombre ==> pointeur sur un short
pusNombre ==> pointeur sur un unsigned short
ppusNombre ==> pointeur sur pointeur sur un unsigned short
etc ...
Ainsi tu auras une programmation beaucoup plus claire et tu ne pourras plus confondre des pointeurs et des variables !
void main()
{
LIST *l;
int i;
int val;
printf("n=");
scanf("%d",&l->n);
Tu as déclaré l comme étant un pointeur sur une structure de type LIST. Pourquoi pas.
Tu utilises ce pointeur l pour y ranger la valeur lue par scanf().
Problème sur quoi pointe l ??? Et bien sur rien car l n'est pas initialisé, autrement dit le scanf() va mettre la valeur saisie quelque part dans la mémoire, pourquoi pas à une adresse qui va tout faire planter, ou qui va corrompre des données.
TU NE PEUX PAS UTILISER DE POINTEURS NON INITIALISE !!!
il faut par exemple que tu ajoutes avant le scanf() :
l = malloc(sizeof(LIST));
if (!l) { gestion d'erreur }
Maintenant l pointe bien sur une zone mémoire correctement définie.
N'oublie pas de désallouer l une fois devenu inutile ( free(l) );
Je n'ai pas été plus loin dans ton code.
Un truc : Utilise la notation hongroise pour bâtir tes noms de variable :
sNombre ==> variable de type short
usNombre ==> variable de type unsigned short
lNombre ==> variable sur un long
etc ...
psNombre ==> pointeur sur un short
pusNombre ==> pointeur sur un unsigned short
ppusNombre ==> pointeur sur pointeur sur un unsigned short
etc ...
Ainsi tu auras une programmation beaucoup plus claire et tu ne pourras plus confondre des pointeurs et des variables !
judy-brainy
Messages postés
15
Date d'inscription
samedi 17 avril 2010
Statut
Membre
Dernière intervention
29 décembre 2010
1
18 avril 2010 à 20:46
18 avril 2010 à 20:46
j'ai bien initialisé ma liste mais jai pas tout ecri ici, sinn ca va prendre de tres longues pages ... merci ;-)
Pacorabanix
Messages postés
3248
Date d'inscription
jeudi 23 août 2007
Statut
Membre
Dernière intervention
19 mai 2013
662
18 avril 2010 à 22:15
18 avril 2010 à 22:15
scanf("%d",&l->n);
esaye plutot :
scanf("%d", &(l->n) );
et teste si la valeur de n est bien enregistrée
esaye plutot :
scanf("%d", &(l->n) );
et teste si la valeur de n est bien enregistrée
judy-brainy
Messages postés
15
Date d'inscription
samedi 17 avril 2010
Statut
Membre
Dernière intervention
29 décembre 2010
1
19 avril 2010 à 18:40
19 avril 2010 à 18:40
merci tout le monde! c'est bon pour l'allocation ... quoi que le programme ne marche toujours pas, et là j'arrive pas a voir c'est où encor le probleme :s car l'operateur se ferme automatiquement en m'indiquant une erreur genre opertion illigale
bon voici le programme complet si jamais vous aurez le temps de tout le lire, mais avant voici son principe: il transforme une expression parenthésée en expression polonaise et ca grâce aux piles et aux files:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#define max 20
typedef struct pile //structure comportant le tableau et son nombre d'elements
{
char t[20];
int n;
} pile;
typedef struct File
{
char t[20];
int n;
} File;
pile creerpilevide()
{
pile *p;
p=(pile*)malloc(sizeof(pile));
p->n=0;
return *p;
}
File creerfilevide()
{
struct File *f;
f=(File*)malloc(sizeof(File));
f->n=0;
return *f;
}
int pilepleine(pile p)
{
return (p.n==max);
}
int pilevide(pile p)
{
return (p.n==0);
}
int filepleine(File f)
{
return (f.n==max);
}
int filevide(File f)
{
return (f.n==0);
}
//===
void empiler(pile *p, char val) // les elements s'ajoutent a la fin
{
if (pilepleine(*p))
{
printf("erreur la pile est pleine");
}
else
{
p->t[(p->n)-1]=val;
(p->n)++;
}
}
char obtenir_element_pile(pile *p) // on obtient le dernier element
{
return p->t[(p->n)-1];
}
void depiler(pile *p)
{
if (pilevide(*p))
{
printf("erreur la pile est vide");
}
else
{
(p->n)--;
}
}
void decG(File *f)
{
int i;
if ((f->n)>=2)
{
for(i=0;i>=(f->n)-2;i++)
// juska lavant derniere case(qui va etre remplacée par la derniere)
{
f->t[i]=f->t[i+1]; // la file d'attente va avancer
}
}
}
void enfiler(File *f, char val) // les elements s'ajoutent a la fin
{
if (filepleine(*f))
{
printf("erreur la file est pleine");
}
else
{
(f->n)++;
f->t[(f->n)-1]=val;
}
}
char obtenir_element_file(File *f) // on obtient le premier element
{
return f->t[0];
}
void defiler(File *f)
{
if (filevide(*f))
{
printf("erreur la file est vide");
}
else
{
decG(f);
// pour defiler la file, elle doit avancer, on fait un decalage gauche
(f->n)--;; // le nombre des elements va se reduire
}
}
// on affiche tous les elements de la file, du premier jusqu'au dernier
void affiche_file(File *f)
{
int i;
char element;
printf("voici l'ecriture polonaise: ");
for(i=0;i<(f->n);i++)
{
element=obtenir_element_file(f);
printf("%c",element);
defiler(f);
}
}
void main()
{
int i;
char *ch;
printf("donner l'operation: \n");
scanf("%s",ch);
char operateur;
struct pile *p;
struct File *f;
*p=creerpilevide();
*f=creerfilevide();
for(i=0;i<strlen(ch);i++)
{
if ((*(ch+i)>='0') && (*(ch+i)<='9')) // verifier si c'est un entier
{
enfiler(f,*(ch+i));
}
else
{
if (((*(ch+i)=='+') || (*(ch+i)=='-')) || ((*(ch+i)=='*') || (*(ch+i)=='/')))
// verif si c'est un operateur
{
empiler(p,*(ch+i));
}
else
{
if (*(ch+i)==')')
{
while (!pilevide(*p))
{
operateur=obtenir_element_pile(p);
depiler(p);
enfiler(f,operateur);
}
}
}
}
}
//affichage de la file
affiche_file(f);
getch();
}
bon voici le programme complet si jamais vous aurez le temps de tout le lire, mais avant voici son principe: il transforme une expression parenthésée en expression polonaise et ca grâce aux piles et aux files:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#define max 20
typedef struct pile //structure comportant le tableau et son nombre d'elements
{
char t[20];
int n;
} pile;
typedef struct File
{
char t[20];
int n;
} File;
pile creerpilevide()
{
pile *p;
p=(pile*)malloc(sizeof(pile));
p->n=0;
return *p;
}
File creerfilevide()
{
struct File *f;
f=(File*)malloc(sizeof(File));
f->n=0;
return *f;
}
int pilepleine(pile p)
{
return (p.n==max);
}
int pilevide(pile p)
{
return (p.n==0);
}
int filepleine(File f)
{
return (f.n==max);
}
int filevide(File f)
{
return (f.n==0);
}
//===
void empiler(pile *p, char val) // les elements s'ajoutent a la fin
{
if (pilepleine(*p))
{
printf("erreur la pile est pleine");
}
else
{
p->t[(p->n)-1]=val;
(p->n)++;
}
}
char obtenir_element_pile(pile *p) // on obtient le dernier element
{
return p->t[(p->n)-1];
}
void depiler(pile *p)
{
if (pilevide(*p))
{
printf("erreur la pile est vide");
}
else
{
(p->n)--;
}
}
void decG(File *f)
{
int i;
if ((f->n)>=2)
{
for(i=0;i>=(f->n)-2;i++)
// juska lavant derniere case(qui va etre remplacée par la derniere)
{
f->t[i]=f->t[i+1]; // la file d'attente va avancer
}
}
}
void enfiler(File *f, char val) // les elements s'ajoutent a la fin
{
if (filepleine(*f))
{
printf("erreur la file est pleine");
}
else
{
(f->n)++;
f->t[(f->n)-1]=val;
}
}
char obtenir_element_file(File *f) // on obtient le premier element
{
return f->t[0];
}
void defiler(File *f)
{
if (filevide(*f))
{
printf("erreur la file est vide");
}
else
{
decG(f);
// pour defiler la file, elle doit avancer, on fait un decalage gauche
(f->n)--;; // le nombre des elements va se reduire
}
}
// on affiche tous les elements de la file, du premier jusqu'au dernier
void affiche_file(File *f)
{
int i;
char element;
printf("voici l'ecriture polonaise: ");
for(i=0;i<(f->n);i++)
{
element=obtenir_element_file(f);
printf("%c",element);
defiler(f);
}
}
void main()
{
int i;
char *ch;
printf("donner l'operation: \n");
scanf("%s",ch);
char operateur;
struct pile *p;
struct File *f;
*p=creerpilevide();
*f=creerfilevide();
for(i=0;i<strlen(ch);i++)
{
if ((*(ch+i)>='0') && (*(ch+i)<='9')) // verifier si c'est un entier
{
enfiler(f,*(ch+i));
}
else
{
if (((*(ch+i)=='+') || (*(ch+i)=='-')) || ((*(ch+i)=='*') || (*(ch+i)=='/')))
// verif si c'est un operateur
{
empiler(p,*(ch+i));
}
else
{
if (*(ch+i)==')')
{
while (!pilevide(*p))
{
operateur=obtenir_element_pile(p);
depiler(p);
enfiler(f,operateur);
}
}
}
}
}
//affichage de la file
affiche_file(f);
getch();
}
18 avril 2010 à 20:45
18 avril 2010 à 21:06
Ensuite, il faut bien que tu comprennes que la structures ne contient pas concrètement le tableau. Elle contient une variable tableau.
Non, la structure comprend bel et bien le tableau. Donc pas besoin, et il ne faut surtout pas allouer le tableau. Sinon le compilateur va râler.
Et c'est là toute l'importance de bien savoir qu'un tableau en C, c'est un pointeur vers le premier élément.
Non, un tableau ce n'est pas un pointeur. Le compilateur le transforme en pointeur seulement dans certains contextes (comme le passage en argument, dans des opérations, ...). Pour le reste, il s'agira d'un tableau en tant que tel.
Cdlt,
18 avril 2010 à 22:12
bon, ceci dit le nom d'un tableau est [i]presque/i un pointeur vers le premier élément... donc en définissant la structure avec int * t ; au lieu de int t[20], ma solution devrait être un peu plus correcte....
alors il suffit donc de faire un malloc pour la structure dans ce cas ? je n'ai pas de compilateur sous la main pour tester.
18 avril 2010 à 22:29
Si tu as : struct Liste *l; tu dois allouer comme tu l'as si bien dit avec malloc(sizeof (struct Liste));
Et il faudra de plus allouer tous les pointeurs dans la structure. Si tu as un tableau : int t[20], l'allocation de la structure dans le heap fera en sorte d'allouer 20 bytes*sizeof(int) cases.
Par contre si tu as int *t, ta solution est effectivement correcte.
19 avril 2010 à 17:05
donc j'imagine que l'allocation se fait au niveau de la fonction de creer_liste_vide ...
je pense aussi qu'à chaque fois j'ajoute un element, je dois lui allouer de la place aussi (donc il va y avoir allocation d'un element)
de même dans supprime_element, je devrai utiliser free()