Problème de structur et de fonction en c

Résolu/Fermé
xave4552 Messages postés 53 Date d'inscription dimanche 16 mars 2008 Statut Membre Dernière intervention 24 février 2018 - 6 sept. 2009 à 11:36
xave4552 Messages postés 53 Date d'inscription dimanche 16 mars 2008 Statut Membre Dernière intervention 24 février 2018 - 7 sept. 2009 à 20:07
Bonjour,
voila je m'attaque tranquillement au structure en c et j'ai quelque petit souci.
Mon compilateur me dit qu'il existe y a une un problème quand je passe mon tableau de structure dans une fonction.
Voila le code:
int Saisi_Entier(){
int resultat;
int nombre = 0;
int ok = 0;
int retour;
while (!ok){
retour = scanf("%d%*[^\n]", &nombre);
if ( !retour ){
/* erreur de saisie, on vide le flux */
int c;
while ( ((c = getchar()) != '\n') && c != EOF);
printf("On vous a demande de saisir un nombre\n");
printf("Veuillez recommencer :");
}
else {
/* reussite de la saisie */
getchar(); /* on enleve le '\n' restant */
ok = 1; /* sort de la boucle */
resultat = nombre;
}
}
return resultat;
}
double Saisi_double_float(){
double resultat;
double nombre = 0;
double ok = 0;
double retour;
while (!ok){
retour = scanf("%lf%*[^\n]", &nombre);
if ( !retour ){
/* erreur de saisie, on vide le flux */
double c;
while ( ((c = getchar()) != '\n') && c != EOF);
printf("On vous a demande de saisir un nombre\n");
printf("Veuillez recommencer :");
}
else {
/* reussite de la saisie */
getchar(); /* on enleve le '\n' restant */
ok = 1; /* sort de la boucle */
resultat = nombre;
}
}
return resultat;
}

void Affchage_choix(void){
//system("clear");
printf("Vous avez les choix suivant:\n");
printf("\t1:Vous créez un point\n");
printf("\t2:Vous afficher les points\n");
printf("\t3:Vous supprimer un point\n");

};

void creation(int nb_element, point *p){
double x, y;
nb_element ++;
p = malloc(nb_element * sizeof(point));
printf("Veuillez entrez la coordonner de x:"); x = Saisi_double_float();
printf("Veuillez entrez la coordonner de y:"); y = Saisi_double_float();
p[nb_element].x = x;
p[nb_element].y = y;
}
void Affich_point(int nb, point *p){
int i;
double buffx, buffy;
buffx = p[i].x;
buffy = p[i].y;
for (i = 0 ; i < nb ; i ++){
printf("Point n°%d\tà pour coordonnées: x:%f\t y:%f\n", i, buffx, buffy);
}

}
int main()
{
int choix;
int nb_element;
struct point* p;
nb_element = -1;
while (choix != 50){

Affchage_choix();
choix = Saisi_Entier();

switch (choix){

case 1:
creation(nb_element, &p);
break;
case 2:
Affich_point(nb_element, &p);
break;
}
}
return 0;
}
je ne comprend pas pourquoi cela ne fonctionne pas. Avant j'utiliser les tableau de variable normal comme cela mais cela est peut être différent avec les structure. Pourtant en regardant sur le net je n'ai pas trouver d'erreur.

5 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
6 sept. 2009 à 12:43
Salut,

Je ne sais pas si tu as mis tout ton code, mais :
il n'y a pas les include,
le type point n'est pas défini
dans le prototype de tes fonctions, tu mets point *p alors que dans le main : struct .... Le typedef a-t-il été défini ?

nb_element vaut -1, donc si tu l'incrémentes avant de réaliser l'allocation, tu ne réserveras rien du tout.
Lorsque tu réalises une allocation de pointeur dans une fonction, il faut passer par un pointeur double.
p[nb_element].x = x;

Tu écris dans une zone non allouée et ce, même si nb_element est positif strictement. Lorsque tu crées un tableau de 5 éléments, le dernier indice du tableau est 4 (et non 5).

Il n'y a pas de correspondance entre le prototype d'Affich_point et l'appel dans le main.

Corrige ces erreurs et recompile. S'il y a toujours des erreurs, repose le nouveau code avec les corrections apportées et s'il te plaît, utilise les balises d'indentation de code (à droite du bouton souligné).


Et enfin quelques bonnes pratiques sur ton code : la gestion des erreurs n'est pas correctement fait. Tu devrais plutôt utiliser strtod et enfin il faut toujours tester le code de retour de malloc pour savoir le résultat de l'allocation.

Cdlt
2
xave4552 Messages postés 53 Date d'inscription dimanche 16 mars 2008 Statut Membre Dernière intervention 24 février 2018
6 sept. 2009 à 17:38
Après beaucoup de simplification et de correction voila le code les fonctions Saisi_Entier et Saisi_double_float fonctionne je les avait utiliser dans un autre programme.
Bon j'ai toujours un problème.
le compilateur me que Point n'est pas déclarer sur la ligne suivante.
t = (Point*) realloc (nb_element * sizeof(struct Point));
Je ne vois ce qui cloche j'ai verifier avec internet et un tutoriel.
Ps mon compilateur est gcc
.


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#include "Routine_divers.h"
struct Point{
    double x,y;
};
int main()
{
    int choix, i;
    int nb_element;
    struct Point *p, *t;

    nb_element = -1;
    while (choix != 50){
        Affchage_choix();
        choix = Saisi_Entier();
        switch (choix){
            case 1:
                nb_element++;
                t = p;
                t = (Point*) realloc (nb_element * sizeof(struct Point));
                if (t == NULL){
                    fprintf(stderr, "Réallocation impossible.\nLe programme va se terminer");
                    free(p);
                    free(t);
                    exit(EXIT_FAILURE);
                }else{
                    printf("Veuillez entrez la coordonner de x:");  t[nb_element].x = Saisi_double_float();
                    printf("Veuillez entrez la coordonner de y:");  t[nb_element].y = Saisi_double_float();
                    p = t;
                }
            break;
            case 2:
                for (i = 0 ; i < nb_element ; i ++){
                    printf("le point à pour coordonnées: x:%f\t y:%f\n", p[nb_element].x, p[nb_element].y);
                }
            break;
        }
    }
    return 0;
}
0
t = (Point*) realloc (nb_element * sizeof(struct Point));
Il connaît 'struct Point' mais pas 'Point', alors il faut mettre:
t = (struct Point*)realloc ...
ou utiliser des 'typedef'.
Bonne continuation.
0
xave4552 Messages postés 53 Date d'inscription dimanche 16 mars 2008 Statut Membre Dernière intervention 24 février 2018
6 sept. 2009 à 18:39
Ok sa fonctionne pour la compilation mais pas pour l'execution.
quand je rentre dans la case 1 il me sort abandon
voiçi le code source:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#include "Routine_divers.h"
struct Point{
    double x,y;
};
int main()
{
    int choix, i;
    int nb_element;
    struct Point *p, *t;

    nb_element = -1;
    while (choix != 50){
        Affchage_choix();
        choix = Saisi_Entier();
        switch (choix){
            case 1:
                nb_element++;
                t = p;
                t = (struct Point*) realloc(t,nb_element * sizeof(struct Point));
                if (t == NULL){
                    fprintf(stderr, "Réallocation impossible.\nLe programme va se terminer");
                    free(p);
                    free(t);
                    exit(EXIT_FAILURE);
                }else{
                    printf("Veuillez entrez la coordonner de x:");  t[nb_element].x = Saisi_double_float();
                    printf("Veuillez entrez la coordonner de y:");  t[nb_element].y = Saisi_double_float();
                    p = t;
                }
            break;
            case 2:
                for (i = 0 ; i < nb_element ; i ++){
                    printf("le point à pour coordonnées: x:%f\t y:%f\n", p[nb_element].x, p[nb_element].y);
                }
            break;
        }
    }
    return 0;
}


Ps j'y est regarder de plus prés et cest la fonction realloc qui pose encore problème
0
A quoi cela sert-il de te répondre ?????????????
fiddy a pris le temps de te préciser:
nb_element vaut -1, donc si tu l'incrémentes avant de réaliser l'allocation, tu ne réserveras rien du tout.
Et tu n'en tiens pas compte... alors ne sois pas surpris que le programme ne fonctionne toujours pas .
Bonne réflexion.
0
D'autre part, mais on est tellement en colère par la non-prise en compte des remarques qui sont faites qu'on n'analyse pas plus avant, il y a une autre grave faute dans la ligne:
t = (struct Point*) realloc(t,nb_element * sizeof(struct Point));
As-tu au moins lu la doc ('man realloc') pour connaître le fonctionnement de la fonction 'realloc'... inutile de répondre je subodore déjà la réponse. Cette fonction alloue une nouvelle zone mémoire (augmentation ou diminution qu'importe) par rapport à l'ancienne zone, y recopie ce qui est possible et désalloue l'ancienne zone...
Vois-tu l'os ?
Au premier passage, le pointeur n'est pas initialisé !!! Et c'est une grosse erreur!
Si tu veux continuer de programmer en 'C', il faut absolument savoir gérer les pointeurs, à savoir:
- déclarer un pointeur,
- initialiser le pointeur,
- utiliser le pointeur,
- libérer le pointeur.
Si tu ne veux pas t'astreindre à ces différentes étapes, il n'y a pas de honte à changer de langage ;-) !
Bonne continuation.
0
Décidemment tu est fâché avec les pointeurs et les allocations:
t = p:
free(p);
free(t);

C'est encore une erreur dans la gestion des zones mémoires.
D'autre part, si 't=NULL', il est inutile de libérer un pointeur qui vaut NULL, que peut-il y avoir à libérer ?
Bonne réflexion.
0

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

Posez votre question
xave4552 Messages postés 53 Date d'inscription dimanche 16 mars 2008 Statut Membre Dernière intervention 24 février 2018
7 sept. 2009 à 20:07
Etourderie de merde lol, merci quand même
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#include "Routine_divers.h"
struct Point{
    double x,y;
};
int main()
{
    int choix, i;
    int nb_element;
    struct Point *p, *t;
    p = NULL;
    t = NULL;
    nb_element = 0;
    while (choix != 50){
        Affchage_choix();
        choix = Saisi_Entier();
        switch (choix){
            case 1:
                nb_element ++;
                t = p;
                t = (struct Point*) realloc(t, nb_element * sizeof(struct Point));
                if (t == NULL){
                    fprintf(stderr, "Réallocation impossible.\nLe programme va se terminer");
                    free(p);
                    exit(EXIT_FAILURE);
                }else{
                    printf("Veuillez entrez la coordonner de x:");  t[nb_element].x = Saisi_double_float();
                    printf("Veuillez entrez la coordonner de y:");  t[nb_element].y = Saisi_double_float();
                    p = t;
                }
            break;
            case 2:
                for (i = 0 ; i < nb_element ; i ++){
                    printf("le point à pour coordonnées: x:%f\t y:%f\n", p[nb_element].x, p[nb_element].y);
                }
            break;
        }
    }
    return 0;
}
0