Problèmes structures C

Fermé
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 - 28 déc. 2007 à 11:34
SebManfred Messages postés 484 Date d'inscription mardi 28 août 2007 Statut Membre Dernière intervention 20 mai 2011 - 28 déc. 2007 à 15:15
Bonjour,
j'ai fait un programme en C sur DEVC++ et je ne comprend pas pourquoi j'obtient la meme chose pour :
ListeAction[nbactions].Vnom et pour ListeAction[nbactions].Vvaleur. Je vous transmet une partie de mon code :

VERS LE DEBUT J'AI CELA:

typedef struct
{
char Vvaleur[];
char Vnom[];
} Action;

MA FONCTION CREERACTION :

Action* creerAction(char* val, char* nom)
{
Action UneAction;
Action *pUneAction=NULL;
pUneAction=&UneAction;
strcpy(UneAction.Vvaleur,val);
strcpy(UneAction.Vnom,nom);
return pUneAction;
}

Puis après une partie de mon main :

int nbactions=30;
Action *pAct=NULL;
Action ListeAction[nbactions];
for (nbactions=0;nbactions<29;nbactions++)
{
pAct=creerAction(nom,valeur);
strcpy(ListeAction[nbactions].Vvaleur,pAct->Vvaleur);
strcpy(ListeAction[nbactions].Vnom,pAct->Vnom);
printf("%s\t%s\n",ListeAction[nbactions].Vnom,ListeAction[nbactions].Vvaleur);
}

Voilà en faite il n'y a pas de problèmes pour les variables nom et valeur mais parfois le programme plante et il me met signaler l'erreur a windows. Sur la ligne de mon printf, j'obtient la même chose pour les deux chaines.
Bon j'espère que vous aurez compris ce qui va pas sinon n'hésitez pas a me le redemender.
merci pour l'aide

8 réponses

SebManfred Messages postés 484 Date d'inscription mardi 28 août 2007 Statut Membre Dernière intervention 20 mai 2011 128
28 déc. 2007 à 11:37
tu initialise bien tout tes champs? en particulier les pointeurs? (meme et surtout les nulls)
0
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 32
28 déc. 2007 à 11:42
Oui tous mes pointeurs sont initialisés. Je pense que le problème se situe au niveau de mon :
Action ListeAction[nbactions];

Parfois quand je lui dit de boucler 10 fois il plante et parfois (comme j'ai fait dans l'exemple avec 29 fois il passe) mais ça c'est normal car la longueur des chaines change toutes les secondes. Je crois que le soucis se trouverai par là.
0
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 32
28 déc. 2007 à 11:44
Bon attend je crois que ça va etre plus simple : je met tout mon code.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <iostream>
#include <curl/curl.h>
#include<conio.h>
#include<time.h>

char recherchenom(char);
char recherchevaleur(char);
void gotoxy(int x,int y);

typedef struct
{
char Vvaleur[];
char Vnom[];
} Action;

Action* creerAction(char* val, char* nom)
{
Action UneAction;
Action *pUneAction=NULL;
pUneAction=&UneAction;
strcpy(UneAction.Vvaleur,val);
strcpy(UneAction.Vnom,nom);
return pUneAction;
}

char *recherchenom(char nom[])
{
int i,j;
int nombre=0;
for (i = j = 0; nom[i] != '\0'; ++i)
{
if (nom[i] =='<' || nom[i] =='>')
nombre++;
if ((nom[i] >= 65 && nom[i] <= 90 || nom[i]==' '|| nom[i]=='-')&&(nombre%2==1))
nom[j++] = nom[i];
}
nom[j] = '\0';
return nom;
}

char *recherchevaleur(char valeur[])
{
int i,j;
for (i = j = 0; valeur[i] != '\0'; ++i)
{
if ((valeur[i] >= 48 && valeur[i] <= 57 || valeur[i]==46))
valeur[j++] = valeur[i];
}
valeur[j] = '\0';
return valeur;
}

void gotoxy(int x,int y)
{
HANDLE hConsoleOutput;
COORD dwCursorPosition;
fflush(stdin);
dwCursorPosition.X=x;
dwCursorPosition.Y=y;
hConsoleOutput=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hConsoleOutput,dwCursorPosition);
}

int main()
{
char caractere[100];
char touche;
char valeur[100];
char nom[100];
int i,j;
int nombre=0;
int nbactions=30;
int nombredeclear=0;

Action *pAct=NULL;
Action ListeAction[nbactions];
char horloge[128];
_tzset();
_strtime(horloge);

while(touche!=27)
{
system("cls");
if (kbhit())
touche=getch();
CURL *session = curl_easy_init();
curl_easy_setopt(session, CURLOPT_URL, "http://www.boursorama.com/palmares/palmares.phtml");
FILE * fp = fopen("palmares[1].txt", "w");
curl_easy_setopt(session, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(session, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_perform(session);
fclose(fp);
curl_easy_cleanup(session);

FILE*fichier=NULL;
fichier=fopen("palmares[1].txt","r");
if (fichier!=NULL)
{
printf("=================ANALYSE BOURSIERE=================\n\n");gotoxy(8,2);printf("nom");gotoxy(30,2);printf("valeur\n");
}
for (nbactions=0;nbactions<29;nbactions++)
{
fseek(fichier,15340+nbactions*610,0); //valeur
fgets(valeur,100,fichier);

fseek(fichier,15278+nbactions*610,0); //nom
fgets(nom,100,fichier);
//printf("chainenom: %s",nom);
//printf("chaineval: %s",valeur);
recherchenom(nom);
recherchevaleur(valeur);
gotoxy(1,nbactions+4);printf("%s",nom);gotoxy(30,nbactions+4);printf("%s",valeur);
pAct=creerAction(nom,valeur);
strcpy(ListeAction[nbactions].Vvaleur,pAct->Vvaleur);
strcpy(ListeAction[nbactions].Vnom,pAct->Vnom);
//printf("%s\t%s\n",ListeAction[nbactions].Vnom,ListeAction[nbactions].Vvaleur);
}
nombredeclear++;
gotoxy(1,nbactions+5);printf("nombre de clear : %d",nombredeclear);
_strtime(horloge);
gotoxy(1,nbactions+6);printf("Heure : %s",horloge);
fclose(fichier);
_sleep(1000);

}
system("pause");
}
/* Il faudrait que je fasse :
-Un tableau qui enregistre tous les changenments de valeurs et l'heure de ces changements pour chaque valeurs.
*/
/* Ce programme ressort les informations qui sont sur le fichier source de la page http://www.boursorama.com/palmares/palmares.phtml.
Mon problème est qu'il ne diférencie pas Vnom et Vvaleur ( j'ai déja mis le printf avec un "//".
De plus, il n'accepte que les boucles d'une certaine longueur. Dans le for, il faut ajuster le nombre maximum pris par nbactions: Je ne sais pas pourquoi. Parfois il n'en prend que 10 et une fois il a ruéssi a m'en prendre 20. Mais comme le fichier change toute els secondes, parfois le programme peut bien débuter et puis s'arreter car le nombre de nbactions est dorénavent trop grand pour lui.
Sinon pour ce qui est de la sélection des données sur le fichier pour le nom ou les valeurs, il y a moyen je pense de l'améliorer mais bon ça ce n'est pas trop important et je le ferait plus tard.
Si vous aviez une idée de ce qui va pas ce serait sympa de me l'expliquer.
Merci
*/
0
SebManfred Messages postés 484 Date d'inscription mardi 28 août 2007 Statut Membre Dernière intervention 20 mai 2011 128
28 déc. 2007 à 12:12
tu créé ta structude "action" dans ta fonction "creeaction", puis tu renvoie son adresse dans un pointeur, mais ta structure a une portée locale, et donc, l'espace mémoire, si il n'est pas écrasé reste bon, et tu peux toujours y accéder en te servant de l'adresse retournée par ton pointeur, mais le stacker peut réattribuer l'espace mémoire, qui, à la sortie de la fonction, n'est plus réservé. c'est un exemple typique d'écrasement mémoire.
il faudrait que tu fasse un malloc pour allouer ton espace mémoire, puis un free quand tu n'en as plus besoin.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 32
28 déc. 2007 à 12:27
C'est quoi un free ?
0
SebManfred Messages postés 484 Date d'inscription mardi 28 août 2007 Statut Membre Dernière intervention 20 mai 2011 128
28 déc. 2007 à 12:32
quand tu fais un malloc, ça t'alloue de la mémoire de façon dynamique, et ça n'est pas soumis à la règle des portées de variables. donc, une fois que tu as fini d'utiliser ton espace mé moire et que tu n'en as plus besoin, il faut le libérer.
pour ça, tu utilise free.

ton code devrait ressembler à ça :

Action* pAction = (Action*)malloc(sizeof(Action)); /* allocation de la mémoire et récupération de l'adresse de la zone allouée dans un pointeur*/
// ton code pour utiliser ta structure
free(pAction)

Attention à ne pas perdre le pointeur pAction en cours de route, car ça, c'est la fuite mémoire (un grand classique)
0
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 32
28 déc. 2007 à 15:03
j'ai pas bien compris où je met ces bouts de codes. Je pensait qu'il fallait les mettre comme suit mais ça ne marche pas :

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <iostream>
#include <curl/curl.h>
#include<conio.h>
#include<time.h>

char recherchenom(char);
char recherchevaleur(char);
void gotoxy(int x,int y);

typedef struct
{
char Vvaleur[];
char Vnom[];
} Action;

Action* creerAction(char* val, char* nom)
{
Action UneAction;
Action *pUneAction=NULL;
pUneAction=&UneAction;
strcpy(UneAction.Vvaleur,val);
strcpy(UneAction.Vnom,nom);
return pUneAction;
}

char *recherchenom(char nom[])
{
int i,j;
int nombre=0;
for (i = j = 0; nom[i] != '\0'; ++i)
{
if (nom[i] =='<' || nom[i] =='>')
nombre++;
if ((nom[i] >= 65 && nom[i] <= 90 || nom[i]==' '|| nom[i]=='-')&&(nombre%2==1))
nom[j++] = nom[i];
}
nom[j] = '\0';
return nom;
}

char *recherchevaleur(char valeur[])
{
int i,j;
for (i = j = 0; valeur[i] != '\0'; ++i)
{
if ((valeur[i] >= 48 && valeur[i] <= 57 || valeur[i]==46))
valeur[j++] = valeur[i];
}
valeur[j] = '\0';
return valeur;
}

void gotoxy(int x,int y)
{
HANDLE hConsoleOutput;
COORD dwCursorPosition;
fflush(stdin);
dwCursorPosition.X=x;
dwCursorPosition.Y=y;
hConsoleOutput=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hConsoleOutput,dwCursorPosition);
}

int main()
{
char caractere[100];
char touche;
char valeur[100];
char nom[100];
int i,j;
int nombre=0;
int nbactions=30;
int nombredeclear=0;

Action *pAct=NULL;
Action ListeAction[nbactions];
char horloge[128];
_tzset();
_strtime(horloge);

while(touche!=27)
{
system("cls");
if (kbhit())
touche=getch();
CURL *session = curl_easy_init();
curl_easy_setopt(session, CURLOPT_URL, "http://www.boursorama.com/palmares/palmares.phtml");
FILE * fp = fopen("palmares[1].txt", "w");
curl_easy_setopt(session, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(session, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_perform(session);
fclose(fp);
curl_easy_cleanup(session);

FILE*fichier=NULL;
fichier=fopen("palmares[1].txt","r");
if (fichier!=NULL)
{
printf("=================ANALYSE BOURSIERE=================\n\n");gotoxy(8,2);printf("nom");gotoxy(30,2);pri ntf("valeur\n");
}
for (nbactions=0;nbactions<29;nbactions++)
{
fseek(fichier,15340+nbactions*610,0); //valeur
fgets(valeur,100,fichier);

fseek(fichier,15278+nbactions*610,0); //nom
fgets(nom,100,fichier);
//printf("chainenom: %s",nom);
//printf("chaineval: %s",valeur);
recherchenom(nom);
recherchevaleur(valeur);
gotoxy(1,nbactions+4);printf("%s",nom);gotoxy(30,nbactions+4);printf("%s&qu ot;,valeur); //C'EST ICI LE DEBUT

Action* pAct = (Action*)malloc(sizeof(Action)); /* allocation de la mémoire et récupération de l'adresse de la zone allouée dans un pointeur*/

pAct=creerAction(nom,valeur);
strcpy(ListeAction[nbactions].Vvaleur,pAct->Vvaleur);
strcpy(ListeAction[nbactions].Vnom,pAct->Vnom);
printf("%s\t%s\n",ListeAction[nbactions].Vnom,ListeAction[nbactions].Vvaleur);
free(pAct); //C'EST ICI LA FIN
}
nombredeclear++;
gotoxy(1,nbactions+5);printf("nombre de clear : %d",nombredeclear);
_strtime(horloge);
gotoxy(1,nbactions+6);printf("Heure : %s",horloge);
fclose(fichier);
_sleep(1000);

}
system("pause");
}
0
SebManfred Messages postés 484 Date d'inscription mardi 28 août 2007 Statut Membre Dernière intervention 20 mai 2011 128
28 déc. 2007 à 15:15
tu n'as pas modifié ta fonction creeaction, et ton retour se fait sur un espace mémoire alloué par la fonction creeaction et qui est soumis aux contraintes de portée d'une variable.
en fait, étant donné que tu de fais pas fraiment d'allocation dynamique, tu n'as pas vraiment besoin de malloc, tu peux te contenter de créer une véritable structure action, mais le malloc, s'il est bien fait, ne pose pas de problèmes.
ta structure Action est à créer dans ton main (ce que tu fais par ton Malloc), et ensuite, il te faut passer un pointeur à cette structure à ta fonction pour que la fonction puisse en modifier le contenu.
toi, tu alloue la mémoire, tu récupère un pointeur vers l'emplacement mémoire alloué, puis tu écrase le pointeur par celui qui t'es retourné par ta fonction creeaction. (pAct=creerAction(nom,valeur); ... TRES MAUVAIS!!!
tu as donc une double erreur : une fuite mémoire du au fait que tu as perdu le lien vers ton espace mémoire alloué de façon dynamique, et un écrasement mémoire lié au fait que tu pointe sur une zone mémoire allouée par une fonction qui a fait son return et qui n'est donc plus réservée.

il faut que tu modifie ta fonction creeaction pour lui passer en paramètre un pointeur vers une structure action.
elle n'aura plus besoin de retour car ta structure action sera directement modifiée par ta fonction.
par contre, pour faire plus propre, tu peux lui faire retourner un booleen, false si la fonction s'est mal déroulée, true sinon.
0