petit prob de segmentation fault

petit prob de segmentation fault - C - Programmation

Marsh Posté le 17-04-2004 à 03:52:51    

Bonsoir,
J'ai fais ce petit bout de code :
 

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "algo_declaration.h"
  4. objet creer_objet(char *name)
  5. {
  6.    objet a;
  7.    a = (objet)malloc(sizeof(struct d_objet));
  8.    strcpy(a->nom, name);
  9.    a->suivant = NULL;
  10.    return a;
  11. }
  12. objet nouvel_objet(char *nom)
  13. {
  14.    objet nouv, p;
  15.    nouv = creer_objet(nom);
  16.    p = debut_liste_objets;
  17.  
  18.    if (p == NULL)
  19.        debut_liste_objets = nouv;
  20.    else{
  21.      
  22.         while ( strcmp(p->nom, nom) && p->suivant != NULL )
  23.                p = p->suivant;
  24.     if (strcmp(p->nom, nom))
  25.      p->suivant = nouv;
  26.  else printf("\nError %s deja declare", nom);
  27.  }
  28. return nouv;
  29. }


 
Avec un truc un peu comme ça dans le algo_declaration.h :
 

Code :
  1. typedef struct d_objet *objet;
  2. typedef struct d_objet
  3. {
  4.    char *nom;
  5.    int type;
  6.    int taille;
  7.    int adresse;
  8.    objet suivant;
  9. } obj;
  10. /* Variable globale */
  11. objet debut_liste_objets;


 
Et ca plante lamentablement sur le strcpy(a->nom, name);  (segmentation fault)
C'est pas comme ça qu'il faut faire ? Help je débute :)
Merci ! :)


---------------
- mon feed-back
Reply

Marsh Posté le 17-04-2004 à 03:52:51   

Reply

Marsh Posté le 17-04-2004 à 04:25:06    

Ben ouais, faut peut-être allouer de l'espace pour a->nom... Fait un strdup plutôt qu'un strcpy.

Reply

Marsh Posté le 17-04-2004 à 08:58:14    

matafan a écrit :

Ben ouais, faut peut-être allouer de l'espace pour a->nom... Fait un strdup plutôt qu'un strcpy.

bof, si la taille des chaines peut être bornée, autant avoir quelque chose en dure (et bien faire gaffe avec un strncpy + '\0')

Reply

Marsh Posté le 17-04-2004 à 12:41:19    

Ah bon ok je pensais que ça allouait de la place pour la chaine nom aussi lorsque je faisais  
 

Code :
  1. a = (objet)malloc(sizeof(struct d_objet));


 
Ok j'essayerai tout à l'heure je vous tiens au courant :crazy:


---------------
- mon feed-back
Reply

Marsh Posté le 17-04-2004 à 15:11:12    

a =  malloc(sizeof *a);

Reply

Marsh Posté le 17-04-2004 à 17:48:35    

Bon ben j'ai mis ça et ça a l'air de plus poser de problème :)
 

Code :
  1. objet creer_objet(char *name)
  2.    objet a;
  3.    a = malloc(sizeof(struct d_objet));
  4.    a->nom = (char *)malloc(strlen(name)+1 * sizeof(char));
  5.    strcpy(a->nom, name);
  6.    a->suivant = NULL;
  7.    return a;
  8. }


 
Enfin si mon compilo me fait un warning car j'ai un malloc non casté, mais bon j'ai cru lire sur ce même forum que c'était pas très bon de caster les malloc non ? donc je laisse comme ça ?
 
Merki :)


---------------
- mon feed-back
Reply

Marsh Posté le 17-04-2004 à 18:20:02    

Zipo a écrit :

Bon ben j'ai mis ça et ça a l'air de plus poser de problème :)
 
Enfin si mon compilo me fait un warning car j'ai un malloc non casté, mais bon j'ai cru lire sur ce même forum que c'était pas très bon de caster les malloc non ? donc je laisse comme ça ?
 
Merki :)


 
Le gros problème des cast est que leur comportement est fortement lié au compilateur ce qui implique, dans des cas un peu tordus ou avec des vieux compilos, un code non portable. De mémoire, l'exemple type se trouve en C++:
 

Code :
  1. class A
  2. {
  3. public:
  4.   A(){}
  5.   ~A(){}
  6.   char proutA[128];
  7. };
  8. class B
  9. {
  10. public:
  11.   B(){}
  12.   ~B(){}
  13.   char proutB[128];
  14. };
  15. class C : public A, public B
  16. {
  17. public:
  18.   C(){}
  19.   ~C(){}
  20.   char proutC[128];
  21. };
  22. void func()
  23. {
  24.   C obj;
  25.   A * a=&obj;
  26.   B * b=&obj;
  27.   C * c=&obj;
  28.   /* ou peut-être:
  29.   C * c=new obj;
  30.   A * a=(A*)c;
  31.   B * b=(B*)c;
  32.   je sais plus :D */
  33.   fprintf(stderr, "%p %p %p\n", a, b, c);
  34. }


 
Selon le compilateur qu'on utilise, on aura :
- trois fois la même adresse
- l'adresse c identique à a et différente de b
- l'adresse c identique à b et différente de a
- trois adresses différentes
 
C'est pour que cela qu'à l'inverse de taz, je pense que le mal vient des cast implicites ou, c'est pareil, du fonctionnement implicite du cast de son compilo. Après caster un malloc, je ne vois pas bien en quoi ce serait problématique, l'inverse par contre...

Reply

Marsh Posté le 17-04-2004 à 18:34:56    

pour ton exemple : l'important c'est qu'on retombe sur ces pattes. si tu utilises les cast explicites du C++ correctement il n'y a aucun problème et tu te soucies peut de l'adresse réel de ton objet. encore un bon exemple qui montre a quel point les cast C sont néfastes en C++.
 
déjà on parle C
 
et surtout, je dis que le cast implicite n'a de sens que s'il est parfaitement défini. je préfère infiniment un cast implicite que des gogos qui foutes des casts dans tous les sens pourvus que ça passe
 
C   T* <-> void*
C++ T*  -> void*
 
sont implicites et c'est très clair que c'est sans risque.

Reply

Marsh Posté le 18-04-2004 à 03:52:12    

Je suis prêt à parier que le warning vient de ce que tu n'inclue pas stdlib.h. Donc le compilo suppose que malloc retoune un int, et il te sort légitimement un warning pour le cast int -> char *. Inclu stdlib et il verra que malloc renvoit un void *.
 
Et puis c'est pas que pour le warning, si tu compiles en 64-bit ton programme ne marchera tout simplement pas sans stdlib.h...

Reply

Marsh Posté le 18-04-2004 à 03:57:16    

ou ne serait-ce à cause de problème de signe ça peut tout foutre en l'air ...
bien vu matafan, j'ai l'impression que mon petit combat sur les cast inutiles et source d'erreur commence à porter ses fruits  :)


Message édité par Taz le 18-04-2004 à 04:05:52
Reply

Marsh Posté le 18-04-2004 à 03:57:16   

Reply

Marsh Posté le 18-04-2004 à 07:16:12    

Ah oui bien vu, j'avais oublié d'inclure stdlib...
Jsuis impardonable ! :crazy:
 
Tout marche impec' merci !


---------------
- mon feed-back
Reply

Marsh Posté le 18-04-2004 à 14:40:38    

Un dimanche où je m'emmerde, je tombe par hasard sur cette page, et ça parle de malloc et de son type de retour. Pile ce qu'il me faut pour mon TP :)
Je n'inclus pas stdlib (juste stdio) dans mon programme, et je caste le retour de malloc en un pointeur de structure. Et ca marche très bien.
Or d'après vos dires, ce serait bancal ?
De même, il semblerait que la constante NULL soit contenue dans stddef.h, pourtant le compilateur la comprend parfaitement malgré la non-inclusion de stddef.h dans mon programme.
 
Bref, j'aimerais savoir quand se passer de ces inclusions, et quand les effectuer. De même, pourquoi le compilateur comprend-il des constantes ou des fonctions définies dans des fichiers que mon programme n'inclut pas ? Merci de m'éclairer (ou de m'indiquer un site capable de le faire) :)
 
PS : non, mon cours n'a pas abordé ce sujet, il y a une sorte de flou sur toute cette partie du C

Reply

Marsh Posté le 18-04-2004 à 15:27:32    

passke l'un des fichiers .h que tu inclus inclue lui-même d'autres fichiers .h.
 
après ça dépends du compilo, et de comment il est foutu...

Reply

Marsh Posté le 23-04-2004 à 11:10:33    

Taz a écrit :

pour ton exemple : l'important c'est qu'on retombe sur ces pattes. si tu utilises les cast explicites du C++ correctement il n'y a aucun problème et tu te soucies peut de l'adresse réel de ton objet. encore un bon exemple qui montre a quel point les cast C sont néfastes en C++.
 
déjà on parle C
 
et surtout, je dis que le cast implicite n'a de sens que s'il est parfaitement défini. je préfère infiniment un cast implicite que des gogos qui foutes des casts dans tous les sens pourvus que ça passe
 
C   T* <-> void*
C++ T*  -> void*
 
sont implicites et c'est très clair que c'est sans risque.


 
Je suis à peu près d'accord avec toi, sauf que :
- si on s'interdit en C++ toute la puissance du C, alors autant faire du java
- il y a très longtemps, dans une autre galaxie, certains programmeurs faisaient du C. Ils utilisaient une arme nommée cast à des fins de transtypage et d'alignement. On était alors sûr que le cast conservait l'adresse "castée". Puis est arrivé le coté obscur de la force: le C++. Et là, il a été difficile à comprendre, pour certains, d'avoir des casts qui effectuent des changements d'adresse (certes, c'est dû à la gestion du polymorphisme mais quand même).

Reply

Marsh Posté le 23-04-2004 à 12:57:30    

y a rien d'obscure si ce n'est n'est l'ignorance. y a pas de toute puissance du C. les cast, moins y en a mieux c'est, le C est faiblement typé, le C++ l'est un peu plus, pour dissuader des casts aux effets ravageurs et imprévisibles, de nouveaux casts sont introduits et sont bien définis

Reply

Marsh Posté le 23-04-2004 à 16:04:57    

Taz a écrit :

y a rien d'obscure si ce n'est n'est l'ignorance. y a pas de toute puissance du C. les cast, moins y en a mieux c'est, le C est faiblement typé, le C++ l'est un peu plus, pour dissuader des casts aux effets ravageurs et imprévisibles, de nouveaux casts sont introduits et sont bien définis


 
L'ignorance de quoi? Du fonctionnement du cast d'un compilo spécifique et de son runtime? Pour ta remarque sur le typage, c'est mignon tout plein de naïveté. Ce que l'on appelle C et C++ ne sont que des ensembles de méta-commandes destinées à un programme de traduction en assembleur. En clair, ce n'est pas une question de typage mais de génération et de structuration au niveau du générateur.

Reply

Marsh Posté le 23-04-2004 à 16:29:09    

métacommande, tu vas prendre froid :o


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 23-04-2004 à 16:41:04    

kadreg a écrit :

métacommande, tu vas prendre froid :o


 
Appelez les comme vous voulez. Ca ne change rien au fait que ce ne sont que des commandes destinées à un logiciel de génération.

Reply

Marsh Posté le 23-04-2004 à 21:33:53    

Le typage est une façon de forcer une certaine rigueur dans la programmation. Si on caste, on s'affranchit des barrières que nous met le compilateur et l'on perd cette rigueur. Dans le cas extrême, il n'est même plus nécessaire de typer les variables à leur déclaration, il suffit de savoir que i est un int et x est un float et c'est la fête du slip assurée.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed