Erreur de segmentation en C

Résolu
LCoileux -  
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour,
débutant en langage C, je veux faire un petit programme, et je bloque dejà au debut...
Voila mon code:

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


typedef struct Element Element;

struct Element{
    char *nomElement;
    int hauteurElement;
};

Element *creerElement(char *nom, int h){
    Element *element;
    strcpy(element->nomElement, nom);
    element->hauteurElement = h;
    return(element);
}

int main(void){
    Element *elt;
    char *tab = "element n° 1";
    elt = creerElement(tab, 10);
    printf("Element de nom %s et de hauteur %d cree !\n", elt->nomElement, elt->hauteurElement);
    return 1;
}


Tout compile, c'est bon, mais quand je le lance, j'obtiens une erreur de segmentation. Après recherche, il semblerait que ca provienne de la fonction strcpy.
Je pense que cela vient du fait que nomElement n'est pas de taille suffisante pour recevoir la chaine de caractères, et que donc je dois lui donner une taille assez grande. Seulement je ne voie pas trop comment faire...
J'ai essayé de passer par un tableau intermédiaire, de faire un malloc,...mais ca n'a pas fonctionné. Comment dois-je faire ?

Merci

4 réponses

chuka Messages postés 965 Date d'inscription   Statut Membre Dernière intervention   378
 
Salut,
il y a 3 façons d'initialiser les pointeur:
-Allocation de mémoire par malloc ((entre autre) (char*m=(char*)malloc(sizeof (char)*20)->alloue sur le tas une zone mémoire de 20 octets, m a pour adresse le premier element)
-Initialisation avec une valeur (int*p=32)
-Initilisation avec une adresse (unsigned short*w=0x2365;unsigned short*ww;ww=w)(ww et w pointe alors sur la meme adresse memoire)

Donc quand tu ecris:
Element *creerElement(char *nom, int h){
Element *element; //(element n'a jamais d'adresse memoire alloué donc plantage pour la suite...car à quelle adresse memoire aller lire ou ecrire!!
strcpy(element->nomElement, nom);//voir ci-dessus...et il faudrait aussi creer un espace memoire pour ton char* ou passer directement l'adresse..
element->hauteurElement = h;
return(element);
}
Element *creerElement(char *nom, int h){
Element *element=(Element*)malloc(sizeof(Element));
element->nomElement=nom;//Attention element->nomElement et nom on //alors la meme adresse!! modification des données pointées de l'un modifie //l'autre
element->hauteurElement = h;
return(element);
}
ou sinon
Element *creerElement(char *nom, int h){
Element *element=(Element*)malloc(sizeof(Element));
char*m=(char*)malloc(sizeof(char)*(strlen(nom)+1));
strcpy(m, nom);
element->nomElement=m;
//dans ce cas modification des données de //l'un ne modifie pas les données de l'autres!!
element->hauteurElement = h;
return(element);
}
J'ai pas testé mais cela devrait fonctionner!!
@+
Ce n'est pas parce que certaines choses semblent inexplicables, qu'il faut faire semblant de les expliquer!
0
tatou_38 Messages postés 1937 Date d'inscription   Statut Membre Dernière intervention   121
 
Utiliser un pointeur non initialiser est mortel, tu viens de le découvrir à tes dépens :

Element *creerElement(char *nom, int h){
Element *element;
strcpy(element->nomElement, nom);
element->hauteurElement = h;
return(element);
}

strcpy copie une chaîne de caractère dans element->nomElement, soit.
Or element est déclaré comme étant un pointeur sur un objet de type Element, mais quel objet ?? Et bien aucun puisque tu ne l'as pas défini, c'est à dire que element pointe sur n'importe quoi ==> PLANTAGE assuré !

il eut fallu par exemple faire :

Element *element = malloc( sizeof(Element) );
strcpy(element->nomElement, nom);

el désallouer element quand tu n'en auras plus besoin !
0
LCoileux
 
Merci, ca fonctionne ! :)
En espérant ne plus avoir d'erreurs :p
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Bonjour,

Element *elt;
Comme dit plus haut, cette instruction ne réserve pas de zone qui pourra recevoir des données. Pour ceci il faut utiliser malloc.
Par exemple : elt=malloc(taille*sizeof(Element));
Ou plus générique : elt = malloc(taille*sizeof(*elt));

Ensuite, il ne faut pas oublier de libérer les ressources avant la fin du programme.
Ceci est très simple : free(elt);

Et enfin, un petit point de détail :
return 1;
C'est return 0; qu'il faut mettre à la fin pour signaler que le programme s'est bien déroulé.

Cdlt,
0