Aller au contenu

[RESOLU] arrachage de cheveux sur les pointeurs


Messages recommandés

mais sérieux, tu parcours un tableau là, un i < coef et on en parle plus !

bas ouais forcement, sauf que ce qui m'interesse c'est de verifier ce que m'a fait malloc.

A supposer dans le monde de l'hypothétique que ta mémoire serait rempli correctement pour ta boucle, tu sort de ta boucle en lisant en dehors d'un espace mémoire alloué

c'est effectivement l'idée que j'avais suivi, maintenant si ya mieux je prend....

pour le code je vous met le tout, le malloc est au début de rf_scores()

je l'ai tester sa compile mais attendez vous a des resultat bizarre

int main(int argc, char *argv[])
{
score joueur1;
memset(&joueur1,0,sizeof(joueur1));//initialisation

printf("\ntapez les entree du joueur :\n-Nom :\t\t");
scanf_s("%s",joueur1.nom,TAILLE);
printf("\n-Moyenne :\t");
scanf_s("%f",&joueur1.moyenne,10);
printf("\n-Partie :\t");
scanf_s("%d",&joueur1.partie,4);
rf_scores(nb_ligne(),&joueur1);

puts("");
system("pause");
return 0;
}
int nb_ligne()
{
int i=0;
char test[TAILLE]="";
FILE *scores=NULL;
scores=fopen("test.txt","r");

if(scores!=NULL)
{
	rewind(scores);
	while(!feof(scores)&&fgets(test,TAILLE,scores)>0)
	{
		i++;
	}
	printf("\nNb de ligne = %d",i);
	fclose(scores);
}
else
{
	printf("impossible d'ouvrir le fichier");
	exit(0);
}
return i;
}

void rf_scores(int coef, score *joueur1)
{
int i=0, j=0;
score *xjoueur=NULL;
FILE *scores=NULL;
xjoueur=malloc(coef*sizeof(*xjoueur));
for(i=0;i<coef;i++)
{
	memset(xjoueur[i].nom,0,sizeof(xjoueur->nom));
	memset(&xjoueur[i].moyenne,0,sizeof(xjoueur->moyenne));
	memset(&xjoueur[i].partie,0,sizeof(xjoueur->partie));
}

if(xjoueur==NULL)
{
	printf("\nallocation memoire impossible");
	exit(0);
}
for(i=0;xjoueur[i].nom;i++)
{
	printf("\n%s %f %d",xjoueur[i].nom,xjoueur[i].moyenne,xjoueur[i].partie);
}
scores=fopen("test.txt","r");
if(scores!=NULL)
{
	rewind(scores);
	while(!feof(scores))
	{
		if(fscanf(scores,"%s %f %d",xjoueur[i].nom,&xjoueur[i].moyenne,&xjoueur[i].partie)!=EOF)
		{
			if(strcmp(xjoueur[i].nom,joueur1->nom)==0)
			{
				xjoueur[i].moyenne=((xjoueur[i].moyenne+joueur1->moyenne)/2);
				xjoueur[i].partie=(xjoueur[i].partie+joueur1->partie);
				j++;
			}		
			i++;
		}
	}
	if(j==0)
	{
		strcpy(xjoueur[coef].nom,joueur1->nom);
		xjoueur[coef].moyenne=joueur1->moyenne;
		xjoueur[coef].partie=joueur1->partie;
	}
	for(j=0;j<=coef;j++)
	{
		printf("\n%s %f %d",xjoueur[j].nom,xjoueur[j].moyenne,xjoueur[j].partie);
	}
}
else exit(0);
free(xjoueur);
fclose(scores);
}

Lien vers le commentaire
Partager sur d’autres sites

  • Réponses 104
  • Créé
  • Dernière réponse
c'est effectivement l'idée que j'avais suivi, maintenant si ya mieux je prend....

for(i=0;i < coef;i++)
{
if( xjoueur[i].nom )
	printf("\n%s %f %d",xjoueur[i].nom,xjoueur[i].moyenne,xjoueur[i].partie);
}

De touet façon, comme l'as dit Mephisto, malloc ne fait rien, il te renvoit juste une adresse mémoire alloué mais ce qu'il y a dedans est inconnu.

Lien vers le commentaire
Partager sur d’autres sites

c'est effectivement l'idée que j'avais suivi, maintenant si ya mieux je prend....

for(i=0;i < coef;i++)
{
if( xjoueur[i].nom )
	printf("\n%s %f %d",xjoueur[i].nom,xjoueur[i].moyenne,xjoueur[i].partie);
}

De touet façon, comme l'as dit Mephisto, malloc ne fait rien, il te renvoit juste une adresse mémoire alloué mais ce qu'il y a dedans est inconnu.

j'utilisait le meme sans le if hier, si je demande sa c'est parce que mon code plante en permanence autour des instruction free() et fclose() (il me renvoie plus de bug si je les vires), et ce sans meme prendre la peine d'executer les instructions précedentes.

du coup j'imagine qu'il doit y avoir un probleme avec malloc, et en fait quelque part cette fonction revient a peut près a faire un

printf(coef)...

Lien vers le commentaire
Partager sur d’autres sites

Il manque les structures pour pouvoir compiler :)

Sinon si tu veux VRAIMENT bidouiller avec la mémoire il y a un bon moyen de le faire avec VS (enfin je sais pas si c'est dispo dans la version express ?) :

- Met un point d'arrêt là où tu veux voir comment ça se passe (par exemple sur l'ouverture du premier for de la fonction rf_scores)

- Lance le programme et fais-le s'arrêter sur le point d'arrêt

- Vas dans le menu Debug -> Windows -> Memory -> Memory1

- La tu as une fenêtre qui s'ouvre qui t'affiche tout le contenu de la mémoire de ton programme. Avec ça tu vas pouvoir voir ce que contient réellement ton tableau

- Dans la barre supérieure de la fenêtre, tapes une adresse mémoire que tu veux voir ou plus simplement le nom d'un pointeur (par exemple xjoueur) pour qu'il t'amène directement voir la mémoire à l'endroit désigné par cette adresse.

Avec ça plus de doutes possibles :francais:

Lien vers le commentaire
Partager sur d’autres sites

Il manque les structures pour pouvoir compiler :)

Sinon si tu veux VRAIMENT bidouiller avec la mémoire il y a un bon moyen de le faire avec VS (enfin je sais pas si c'est dispo dans la version express ?) :

- Met un point d'arrêt là où tu veux voir comment ça se passe (par exemple sur l'ouverture du premier for de la fonction rf_scores)

- Lance le programme et fais-le s'arrêter sur le point d'arrêt

- Vas dans le menu Debug -> Windows -> Memory -> Memory1

- La tu as une fenêtre qui s'ouvre qui t'affiche tout le contenu de la mémoire de ton programme. Avec ça tu vas pouvoir voir ce que contient réellement ton tableau

- Dans la barre supérieure de la fenêtre, tapes une adresse mémoire que tu veux voir ou plus simplement le nom d'un pointeur (par exemple xjoueur) pour qu'il t'amène directement voir la mémoire à l'endroit désigné par cette adresse.

Avec ça plus de doutes possibles :craint:

je pense que sa revient au meme que le positionnement de la souris sur - par exemple- "xjoueur.nom"qui me detaille chaque "case" de nom (nom est un tableau[100]).

par exemple pour ce cas xjoueur.nom m'indique "CXX0030 : erreur : impossible d'evaluer l'expression" pourtant le printf me donne, pour ce for, les valeur 0 partout, ce qui est logique puisqu'il arrive jutste après mon initialisation.

maintenant sa m'a quand meme permis de decouvrir une ligne de commande sous visual studio :francais:

Lien vers le commentaire
Partager sur d’autres sites

Justement avec cette fenêtre tu pourras voir pourquoi tu obtiens cette erreur puisque tu vois exactement ce qu'il y a en mémoire et non la vision "simplifiée" que te fournit le débogeur

je vais y jeter un serieux coup d'oeil...

sinon

[ERRATUM]

dans mon code l'erreur sur le free provient bien du malloc qui doit etre egale a (coef+1)*sizeof pour que je puisse executer correctement ma boucle d'ecriture si le nom n'a pas été trouver.

[ERRATUM 2]

il fallait egalement que je repositionne i a 0 juste après l'ouverture de mon fichier pour que sa valeur corresponde dans la boucle while suivante.

bon voila maintenant mon code s'execute parfaitement avec fclose() et free(), pourtant j'ai encore l'impression d'avoir des erreur a l'interieur a cause des fenetre "AUTOMATIQUE" et "MODULES" du debugger.

Modules

debuggermodules.png

Automatiques

debuggervariablelocales.png

peut etre effectivement que les screen comme sa seront pas très parlant, vue qu'il ne sagit que de "symptome" disparate, mais si vous avez une idée ou je dois chercher ...

Ton tableau a coef cases, pas coef + 1. Là, c'est écriture en dehors de mémoire allouée.

ha! ta été plus rapide que moi

Lien vers le commentaire
Partager sur d’autres sites

bon voila je pense etre arrivé a mon objectif conernant le stockage de mes scores en fichier et leur traitement.

je vous met le code en lien histoire de pas surchargé mon post et d'aérer un peut le texte.

j'ai essayer de faire un code exhaustif qui traite l'ensemble des cas que pourrait me présenter un user qui l'utiliserais.

scoring.c

si vous relever des incohérence, des manques ou des possiblités d'optimisation et que vous voulez m'en faire part, sa m'interesse.

concernant les deux screen au dessus ils sont toujour d'actualité bien que le code fonctionne.

quoi qu'il en soit, encore une fois, trop cool pour votre aide sans laquelle je gallererai encore.

et aussi pour votre patiente. :zarb: ++.

Lien vers le commentaire
Partager sur d’autres sites

C'est quoi ton problème avec l'espion et les modules :cartonrouge: je ne vois rien d'anormal là-dedans

bas xjoueur est ...<ptr> incorrect et puis je vois pas pourquoi les modules sont constatment affichés non chargés ... à moins que se soit parfaitement normale mais dans ce cas pourquoi m'affiché sa.

[EDIT] et j'ai toujours CXX0030 : erreur : impossible d'evaluer l'expression pour les element de xjoueur

Lien vers le commentaire
Partager sur d’autres sites

C'est tout à fait normal si les symboles des modules système ne sont pas chargés : ça signifie seulement que tu ne pourras pas débugger le code de ces modules, mais tu peux toujours les éxecuter.

Pour ce qui est de ta variable xjoueur c'est tout à fait normal qu'il te dise valeur incorrecte car la variable est nulle (égale à 0) ! Or c'est impossible de lire des données à l'emplacement mémoire 0, d'où erreur...

Lien vers le commentaire
Partager sur d’autres sites

le problème vient pas forcément d'un malloc

ça peut aussi être une connerie à l'initialisation, une erreur dans ton algo de traitement, ...

et peu importe comment c'est arrivé : tu es devant le problème, t'as le choix entre le basher ou segfaulter.

a toi de voire :chinois:

Lien vers le commentaire
Partager sur d’autres sites

je parle d'un élément de ta liste à null ; c'est ça le problème.

enfin, dans l'absolu, quand tu es parti pour traiter un élément, et qu'il s'avère ne pas être initialisé... ben... ça bug.... et c'est problématique :)

bas je vois pas de xjoueur[x].*** non initialisé ...?

[EDIT]

a ouais je crois que je vois, je sais pas si ta vu mais j'ai mis un lien^^ vers scoring.c du coup je pensais que tu me parlais de ce code la. :francais:

mais effectivement, dans le code que j'ai posté juste avant si je malloc(coef+1), je dois logiquement aussi memset(coef+1).

dans le code de scoring j'avais fait un calloc(), plus simple a mon gout (meme si d'après ce que j'ai pus lire question initialisation sur les type float et autre double c'etait pas toujours ça.... mais j'en sais pas plus)

alors par contre, concernant les pointeur de pointeur et autre pointeur de tableau, ya des truc particulier a connaitre, question fonctionnement ?? par ce que j'en ai utilisé 1 aujourd'hui et je me suis pas mal pris la tete a avec...

Lien vers le commentaire
Partager sur d’autres sites

Y a un truc très bizarre dans ton code et je pense que c'est de là que viens l'erreur. C'est ton "coef+1" qui m'a mis la puce à l'oreille puisque normalement tu devrait créer de la place pour X élément et pas pour X+1 éléments.

En gros ton problème est au niveau de de boucles for de la fonction rf_scores : en effet tu teste la fin de la boucle avec i<=coef, ce qui est faux car il va dépasser le tableau d'un élément ! Il faut toujours utiliser une comparaison strictement inférieure (comme dans ton premier for : i < coef)

Et du coup dans le calloc allouer de la place pour coef éléments, et non pour coef+1 éléments, ce qui est beaucoup plus logique tout de suite :)

Lien vers le commentaire
Partager sur d’autres sites

Y a un truc très bizarre dans ton code et je pense que c'est de là que viens l'erreur. C'est ton "coef+1" qui m'a mis la puce à l'oreille puisque normalement tu devrait créer de la place pour X élément et pas pour X+1 éléments.

En gros ton problème est au niveau de de boucles for de la fonction rf_scores : en effet tu teste la fin de la boucle avec i<=coef, ce qui est faux car il va dépasser le tableau d'un élément ! Il faut toujours utiliser une comparaison strictement inférieure (comme dans ton premier for : i < coef)

Et du coup dans le calloc allouer de la place pour coef éléments, et non pour coef+1 éléments, ce qui est beaucoup plus logique tout de suite :)

si je met X+1 element c'est au cas ou mon joueur est pas présent dans le fichier :

je m'explique :

si joueur présent dans le fichier, ont modifie ces valeur et ont verifie que la derniere ligne (coef+1) n'a pas été modifier.

si le joueur n'est pas présent alors on le place a la dernière ligne (+1) prevue vide pour un joueur qui n'a pas encore été enregistré.

ont fprintf le resultat dans le fichier après l'avoir vidé.

mais c'est vrai que dans ce cas un i<coef+1 serait surement plus propre.

[edit]

concernant le probleme avec le pointeur de tableau voici l'hisoire :

void l_read(char *input[])
{
//fonction qui compte uniquement le nombre de ligne
int i=0, k=0, MAX=0, X=0;
const int MIN=1;
unsigned int t = (unsigned int)time(NULL);
char test[TAILLE]="";
FILE *lib=NULL;
lib=fopen("test.txt","r");
if(lib!=NULL)
{
	rewind(lib);
	while(!feof(lib)&&fgets(test,TAILLE,lib)>0)
	{
		i++;
	}
	printf("\n\ni = %d\n",i);
	MAX=i;
	rewind(lib);
	srand(t);
	X = (rand() % (MAX - MIN + 1)) + MIN;
	for(k=0;k<X;k++)
	{
		fscanf(lib,"%s",test);
	}
	fclose(lib);
}
else
{
	printf("impossible d'ouvrir le fichier");
	exit(0);
}
strcpy(input,test);
}

sachant que

#define TAILLE 100
char input[TAILLE]="";//input est un tableau destiné a recevoir la string selectionnée par la fonction précedente
l_read(input);// j'envoie input comme ceci.

et bien que sa fonctionne (sa me tire un mot aleatoire dans mon fichier), et sa modifie mon tableau en conscéquence, il arrete pas de me renvoyer des warnings :

1>.\main.c(103) : warning C4047: 'fonction' : 'char *' diffère de 'char **' dans les niveaux d'indirection
1>.\main.c(103) : warning C4024: 'strcpy' : types différents pour le paramètre formel et réel 1

sans parler de ceux conercant la saisie sécurisé.

j'arrive pas a trouver comment les eviter.

Lien vers le commentaire
Partager sur d’autres sites

void l_read(char *input[])

Tu as écrit char **, normal qu'il t'envoit chier.

void l_read(char *input)

!!

d' 1/ je sais mais après tout main le fait bien lui avec sont *argv[]

d' 2/ avec un (char *input) mon strcpy devrait etre comme sa strcpy(*input) pour agir sur mon tableau initial, et sa strcpy est pas d'accord avec...

alors que la si je me trompe pas j'ai un pointeur sur chaque ellement de mon input...???

sinon question controle du malloc() j'ai lu que : sur les pointeur, il existait le stack qui contient se information de controle et le heap qui contient les data. d'un autre coté, lorsque on malloc() un pointeur ce dernier doit connaitre, j'imagine, les adresse de debut et de fin (dans son stack ???) et donc permettre de verifier ce que malloc a foutu.??

Lien vers le commentaire
Partager sur d’autres sites

d' 2/ avec un (char *input) mon strcpy devrait etre comme sa strcpy(*input) pour agir sur mon tableau initial, et sa strcpy est pas d'accord avec...

Sauf que justement, ton compilateur lui il fait ce que je dit, et donc attend que input soit un char *, et c'est pour ça que tu as un warning.

Ensuite, il faut rappeler que *input est, dans ton appel, un char, plus précisément le premier de ton tableau. Je dis ca parce que tu passes en paramètre lors de l'appel de ta fonction un char * (ou char []) ((char input[TAILLE]="";))

strcpy attend justement un char *, pas de déréfrencement à faire.

d' 1/ je sais mais après tout main le fait bien lui avec sont *argv[]

Oui, sauf que dans le cas du main, argv est exactement du bon type, c'est à dire un pointeur sur pointeur de char, ou, dans la pratique, un tableau de chaine de caractère. Pas UNE chaîne.

A supposer que tu veuilles faire un strcpy sur argv, il faudrait faire strcpy(argv,...

j'ai un pointeur sur chaque ellement de mon input

Non, tu as un pointeur sur le premier élément de input. Rien d'autre. C'est une chaîne de caractères.

sinon question controle du malloc() j'ai lu que : sur les pointeur, il existait le stack qui contient se information de controle et le heap qui contient les data. d'un autre coté, lorsque on malloc() un pointeur ce dernier doit connaitre, j'imagine, les adresse de debut et de fin (dans son stack ???) et donc permettre de verifier ce que malloc a foutu.??

J'ai du mal à saisir le sens de ta question

Lien vers le commentaire
Partager sur d’autres sites

sinon question controle du malloc() j'ai lu que : sur les pointeur, il existait le stack qui contient se information de controle et le heap qui contient les data. d'un autre coté, lorsque on malloc() un pointeur ce dernier doit connaitre, j'imagine, les adresse de debut et de fin (dans son stack ???) et donc permettre de verifier ce que malloc a foutu.??

J'ai du mal à saisir le sens de ta question

"logiquement" lorsque je malloc() un pointeur, après je peut acceder a chaque element par pointeur.

malloc reserve de l'espace en memoire dans le heap, et les informations de controle propre au pointeur sont conserver dans le stack : si j'ai bien compris le stack doit conserver l'adresse de debut et l'adresse de fin de la zone memoire qui m'à été alloué.

partant de la est il possible de recupéré ces informations pour controler l'allocation qui a été faite. (plutot que d'utilisé le for(i=0;i<x;i++)) ??

[edit]

et effectivement sans les corchet [ ] sa marche aussi bien, :yes:

Lien vers le commentaire
Partager sur d’autres sites

Que quelqu'un me reprenne si je me trompe, mais malloc() et free() doivent appeler des services fournis par l'OS pour l'allocation en mémoire. Ce qui fait que le gestionnaire de mémoire est au courant de la taille et de la position des blocs mémoire alloués. Mais il ne me semble pas qu'il fournissent un service listant ces blocs, et à vrai dire je ne vois même pas pourquoi tu souhaiterais l'utiliser. Ni même ce que viens faire une boucle for dans le tas...

Si malloc() retourne NULL, alors l'allocation a échoué. Sinon tu as bien une adresse stockée dans ton pointeur. Par défaut, l'état de l'espace mémoire alloué est inconnu, et doit être initialisé avant d'être utilisé. Le pointeur lui-même ne sait pas s'il se trouve en début de cette zone, au milieu, à la fin ou en-dehors. C'est aussi simple que ça.

Après libre à toi de créer une structure avec plus d'informations que juste une adresse si tu penses en avoir besoin. Mais pour des programmes simple ça n'est pas forcément utile.

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.


×
×
  • Créer...