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
Bonjuor tout le monde
j'ai un probleme au niveau de ce programme
en fait, apparemment c'est un probleme d'allocation, parceque lorsque j'utilise pas un appel de fonction (j'ecris toutes les instructions au niveau du proramme principal), tout marche tres bien; sinn, si je dois faire appel à une fonction, bien sur je dois utiliser un pointeur (passage par adresse), lorsqu'il s'agit de type simples (entiers, caracteres ...) de même, aucun souci... mais des qu'il s'agit d'un tableau dans une structure, et un passage par adresse ... c'est la pagaille!!! des que je change un champs, comme si il ya initialisation totale des autres champs!!
comment ecrire malloc? ou est ce que je dois la saisir??
j'ai besoin de faire une allocation statique de tableau (tableau statique)

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

typedef struct lst
{
int t[20]; //un tableau
int n; //nombre des elements de ce tableau
} LIST;

void ajout_fin(LIST *l, int val) //passage par adresse
{
int i;
l->n++; //incrémentation du nombre des elements
l->t[l->n-1]=val; //insertion de la valeur dans la derniere case
}

void main()
{
LIST *l;
int i;
int val;

printf("n=");
scanf("%d",&l->n);

//saisie du tableau

for(i=0;i<l->n;i++)
{
printf("donner l'element n°%d \n:",i);
scanf("%d",&l->t[i]);
}

//ajout d'un element a la fin

printf("donner l'element à ajouter a la fin: \n");
scanf("%d",&val);

ajout_fin(l, val);

printf("affichage du tableau: \n");
for(i=0;i<l->n;i++)
{
printf("t[%d]=%d \n",i,l->t[i]);
}


getch();
}



ce programme n'est qu'une partie d'un programme sur lequel je travaille depuis des semaines et je crois que ce detail qui bloque tout !! :s
j'ai tres besoin que ca marche!!

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
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 :

//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.
0
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:45
ahh d'accord, voila un truc que je viens de connaitre, je peux pas donc insérer un tableau dans une structure ... pourtant ca m'indique aucune erreur ... donc je vai revoir mon conde et esperons que ca marche cette fois ci merci ;-)
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
18 avril 2010 à 21:06
Salut Pacorabanix,

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,
0
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:12
arf je me suis fourvoyé! merci fiddy d'être derrière moi...

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.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
18 avril 2010 à 22:29
La règle est très simple : on n'alloue que les pointeurs.
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.
0
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 à 17:05
l'allocation doit être faite dans le programme principal ou dans les fonctions? ... en fait ici je n'ai écrit qu'une seule fonction, mais yen a d'autres (ajout_element, supprime_element, creer_liste_vide ...)
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()
0
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
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 !
0
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
j'ai bien initialisé ma liste mais jai pas tout ecri ici, sinn ca va prendre de tres longues pages ... merci ;-)
0
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
scanf("%d",&l->n);

esaye plutot :

scanf("%d", &(l->n) );

et teste si la valeur de n est bien enregistrée
0
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
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();

}
0