struct

struct - C - Programmation

Marsh Posté le 29-05-2009 à 14:03:36    

bonjour à tous,
je travaille sur un modèle constitué d'une dizaine de sous-programmes. j'ai écris un makefile pour tout compiler au même temps et faire les liens.
je compile avec g++, j'obtiens le fichier executable mais avec des warnings. quand je lance l'exécution j'obtiens: segmentation fault. (je travaille sous linux)
 
voilà le genre de warning:
 
g++ -W -Wall -ansi -pedantic -Dlinux -O2 -c -o Advect.o Advect.c  
main.h:72: warning: non-local variable '<anonymous struct> recap' uses anonymous type
 
dans le main.h, la structure est la suivante:
EXTERN struct
        {
                char nom1[NB_CARACTERES_MAX_CHAINE] ;  
                char nom2[NB_CARACTERES_MAX_CHAINE] ;  
 
                char nom3[NB_CARACTERES_MAX_CHAINE] ;  
                char nom4[NB_CARACTERES_MAX_CHAINE] ;      
                char nom5[NB_CARACTERES_MAX_CHAINE] ;
                char nom5[NB_CARACTERES_MAX_CHAINE] ;  
                char nom6[NB_CARACTERES_MAX_CHAINE] ;  
                char nom7[NB_CARACTERES_MAX_CHAINE] ;          
        }
        recap;
 
 et dans le programme principal main.c:
 #include <string.h>
 #include "main.h"
 
  int main ( int argc, char *argv[] )
 {
   strcpy(chemin_fich_recap,argv[1]);
 
Est-ce que quelqu'un a une idée. marci beaucoup

Reply

Marsh Posté le 29-05-2009 à 14:03:36   

Reply

Marsh Posté le 29-05-2009 à 14:09:59    

bah si ton EXTERN c'est en fait un extern, alors tu n'as fait que déclarer ta variable, elle n'est donc pas allouée.

Reply

Marsh Posté le 29-05-2009 à 14:14:33    

Taz a écrit :

bah si ton EXTERN c'est en fait un extern, alors tu n'as fait que déclarer ta variable, elle n'est donc pas allouée.


 
mais le broblème, c'est pas moi qui ai écrit tous ces programmes, c'est tout un modèle et il marchait sous windows, sauf si les gens qui me l'ont envoyer ont oublié quelque chose. justement je comprenais pourquoi il l'ont mis en EXTERN alors que je le trouve nul par ailleurs.  
 
je devrais peut etre enlever le extern?  

Reply

Marsh Posté le 29-05-2009 à 14:16:56    

t'as nulle par recap dans ton fichier main.c ?

Reply

Marsh Posté le 29-05-2009 à 14:18:06    

tu fais dans ton .h
 
struct Foo { ...; };
 
extern struct Foo recap;
 
et dans ton main.c , en dehors de toutes fonctions, tu fais
 
struct Foo recap = { init };

Reply

Marsh Posté le 29-05-2009 à 14:20:53    

Taz a écrit :

t'as nulle par recap dans ton fichier main.c ?


 
non il existe pas, j'ai fait un grep, et c'est juste dans le main.h.
c-à-d, c'est utilisé pour lire les fichiers d'entrées dans entrees.c
 
void fichiers_entrees_sorties ()
{
        FILE* fp ;
 
        fp = fopen ( chemin_fich_recap, "rt" ) ;
 
        fscanf ( fp,"%s", recap.nom1 ) ;
         

Reply

Marsh Posté le 29-05-2009 à 14:26:28    

bah fais ce que je te dis alors

Reply

Marsh Posté le 29-05-2009 à 14:26:29    

Taz a écrit :

tu fais dans ton .h
 
struct Foo { ...; };
 
extern struct Foo recap;
 
et dans ton main.c , en dehors de toutes fonctions, tu fais
 
struct Foo recap = { init };


 
c-à-d, il faudra donner un nom au struct (définition) après le mettre en extern. (pour moi un extern est définit ailleurs dans les autres prog et utilisé ensuite par le fichier .h où il est mis en EXTERN)
après il faudra l'initialiser? comment puisque c'est des chaines de caractères.
 
en fait je connaissais pas du tout le C, et là je me retouve avec un modèle énorme tout écrit en C.

Reply

Marsh Posté le 29-05-2009 à 14:28:30    

extern = objet défini dans une autre unité de compilation
 
pour l'initialisation, si tu ne peux pas faire = { "pouet", "blah", ...}, il faut qu'en début de programme, tu renseignes tout ça avec des strcpy.
 
Par défaut, tout sera à 0 (donc châine vide)

Reply

Marsh Posté le 29-05-2009 à 14:30:51    

Taz a écrit :

extern = objet défini dans une autre unité de compilation
 
pour l'initialisation, si tu ne peux pas faire = { "pouet", "blah", ...}, il faut qu'en début de programme, tu renseignes tout ça avec des strcpy.
 
Par défaut, tout sera à 0 (donc châine vide)


 
Ok, je vais essayer de modifier tout ça en espérant que ça marchera.
 
je te remercie beaucoup pour ton aide.

Reply

Marsh Posté le 29-05-2009 à 14:30:51   

Reply

Marsh Posté le 29-05-2009 à 14:30:52    

struct  
        {  
                char nom1[NB_CARACTERES_MAX_CHAINE] ;    
                char nom2[NB_CARACTERES_MAX_CHAINE] ;  
 
                char nom3[NB_CARACTERES_MAX_CHAINE] ;    
                char nom4[NB_CARACTERES_MAX_CHAINE] ;      
                char nom5[NB_CARACTERES_MAX_CHAINE] ;  
                char nom5[NB_CARACTERES_MAX_CHAINE] ;  
                char nom6[NB_CARACTERES_MAX_CHAINE] ;  
                char nom7[NB_CARACTERES_MAX_CHAINE] ;          
        }  
        recap;

Cette définition, sans EXTERN, est tout à fait correcte. Le nom de la structure, "recap", peut se mettre sur la même ligne que l'accolade fermante, ou sur la ligne d'après, cela n'a pas importance. Il n'est pas nécessaire de passer par la définition d'une structure, puis de l'associer à recap, mais on pourait le faire si on le voulait, et cela ne changerait rien.
 
Le mot "EXTERN" (en majuscules) ne fait pas partie des mots réservés du C. Il faut donc que ce mot soit défini quelque part, par un #define EXTERN ..., probablement dans un fichier ".h".
 
Il n'est pas nécessaire d'initialiser la structure, mais on peut le faire si on le veut.

Message cité 1 fois
Message édité par olivthill le 29-05-2009 à 14:33:46
Reply

Marsh Posté le 29-05-2009 à 14:34:31    

olivthill a écrit :

struct  
        {  
                char nom1[NB_CARACTERES_MAX_CHAINE] ;    
                char nom2[NB_CARACTERES_MAX_CHAINE] ;  
 
                char nom3[NB_CARACTERES_MAX_CHAINE] ;    
                char nom4[NB_CARACTERES_MAX_CHAINE] ;      
                char nom5[NB_CARACTERES_MAX_CHAINE] ;  
                char nom5[NB_CARACTERES_MAX_CHAINE] ;  
                char nom6[NB_CARACTERES_MAX_CHAINE] ;  
                char nom7[NB_CARACTERES_MAX_CHAINE] ;          
        }  
        recap;

Cette définition, sans EXTERN, est tout à fait correcte. Le nom de la structure, "recap", peut se mettre sur la même ligne que l'accolade fermante, ou sur la ligne d'après, cela n'a pas importance. Il n'est pas nécessaire de passer par la définition d'une structure, puis de l'associer à recap, mais on pourait le faire si on le voulait, et cela ne changerait rien.
 
Le mot "EXTERN" ne fait pas partie des mots réservés du C. Il faut donc que ce mot soit défini quelque part, par un #include EXTERN ..., probablement dans un fichier ".h".


 
Merci, justement, il a été définit dans le main.h
#ifdef _MAIN
#define EXTERN
#else
#define EXTERN extern
#endif
 mais pourquoi alors le warnique comme quoi la structure est anonyme.

Reply

Marsh Posté le 29-05-2009 à 14:38:46    

La definition de EXTERN est correcte.
 
En fait, le problème n'existe pas.
 
main.h:72: warning: non-local variable '<anonymous struct> recap' uses anonymous type
Ce message est juste un avertissement (warning), mais il ne signale pas une véritable erreur.
Il dit juste qu'il manque le tag (selon la dénomination de K& R) de la structure. Mais ce tag n'est pas obligatoire, et n'aurait aucune utilité particulière dans le programme tel qu'il est montré ici.
Pour que le warning disparaisse, il suffirait d'écrire :

EXTERN struct  _recap
        {  
                char nom1[NB_CARACTERES_MAX_CHAINE] ;    
                char nom2[NB_CARACTERES_MAX_CHAINE] ;    
   
                char nom3[NB_CARACTERES_MAX_CHAINE] ;    
                char nom4[NB_CARACTERES_MAX_CHAINE] ;        
                char nom5[NB_CARACTERES_MAX_CHAINE] ;  
                char nom5[NB_CARACTERES_MAX_CHAINE] ;    
                char nom6[NB_CARACTERES_MAX_CHAINE] ;    
                char nom7[NB_CARACTERES_MAX_CHAINE] ;            
        }  
        recap;


 

Reply

Marsh Posté le 29-05-2009 à 14:45:33    

olivthill a écrit :

La definition de EXTERN est correcte.
 
En fait, le problème n'existe pas.
 
main.h:72: warning: non-local variable '<anonymous struct> recap' uses anonymous type
Ce message est juste un avertissement (warning), mais il ne signale pas une véritable erreur.
Il dit juste qu'il manque le tag (selon la dénomination de K& R) de la structure. Mais ce tag n'est pas obligatoire, et n'aurait aucune utilité particulière dans le programme tel qu'il est montré ici.
Pour que le warning disparaisse, il suffirait d'écrire :

EXTERN struct  _recap
        {  
                char nom1[NB_CARACTERES_MAX_CHAINE] ;    
                char nom2[NB_CARACTERES_MAX_CHAINE] ;    
   
                char nom3[NB_CARACTERES_MAX_CHAINE] ;    
                char nom4[NB_CARACTERES_MAX_CHAINE] ;        
                char nom5[NB_CARACTERES_MAX_CHAINE] ;  
                char nom5[NB_CARACTERES_MAX_CHAINE] ;    
                char nom6[NB_CARACTERES_MAX_CHAINE] ;    
                char nom7[NB_CARACTERES_MAX_CHAINE] ;            
        }  
        recap;


 


 
Ok c'est plus clair pour moi maintenant, mais comment pourrais-je savoir ce qui cause l'erreur de segmentation?
 
quand je fai: gdb modèle.exe
 
il dit que l'erreur est dant la fonction main et strcpy mais pas plus de détails que ça

Reply

Marsh Posté le 29-05-2009 à 14:48:55    

il me met aussi le warning:
 
Main.c:182: warning: unused parameter 'argc'
 
quand je debug
gdb modèle.exe, j'obtiens:
 
Program received signal SIGSEGV, Segmentation fault.
0x00002aeea0172d4a in strcpy () from /lib64/libc.so.6
(gdb) bt
#0  0x00002aeea0172d4a in strcpy () from /lib64/libc.so.6
#1  0x000000000040644e in main ()


Message édité par lyn24 le 29-05-2009 à 14:55:00
Reply

Marsh Posté le 29-05-2009 à 14:55:37    

strcpy s'arrête au premier zéro binaire trouvé. Il doit probablement manquer ce caractère zéro de fin de chaine.
 
Pour l'autre warning, le mot "unused" veut dire "inutilisé. Et en effet, cette variable n'est pas utilisée, d'après ce que l'on peut voir du programme.
 
Je devine, qu'il faudrait tester argc > 0, car sinon strcpy(chemin_fich_recap,argv[1]); part dans les choux.

Message cité 2 fois
Message édité par olivthill le 29-05-2009 à 14:58:38
Reply

Marsh Posté le 29-05-2009 à 14:57:48    

olivthill a écrit :

strcpy s'arrête au premier zéro binaire trouvé. Il doit probablement manquer ce caractère zéro de fin de chaine.
 
Pour l'autre warning, le mot "unused" veut dire "inutilisé. Et en effet, cette variable n'est pas utilisée, d'après ce que l'on peut voir du programme.


 
donc est-ce que c'est un problème de longueur de chaine? [NB_CARACTERES_MAX_CHAINE]= 120

Reply

Marsh Posté le 29-05-2009 à 15:01:03    

Je viens d'édier mon message. Je me demandais si un nom de fichier est bien donné en paramètre, car, sauf erreur, c'est là où il y a le strcpy(). Pour recap...., c'est un fscanf, pas, un strcpy.

Reply

Marsh Posté le 29-05-2009 à 15:02:39    

olivthill a écrit :

strcpy s'arrête au premier zéro binaire trouvé. Il doit probablement manquer ce caractère zéro de fin de chaine.
 
Pour l'autre warning, le mot "unused" veut dire "inutilisé. Et en effet, cette variable n'est pas utilisée, d'après ce que l'on peut voir du programme.
 
Je devine, qu'il faudrait tester argc > 0, car sinon strcpy(chemin_fich_recap,argv[1]); part dans les choux.


 
et si au lieu de mettre: strcpy(chemin_fich_recap,argv[1])
je met directement le chemin: un fichier qui contient tous les chemins des fichiers d'entrée et de sortie et puis je lance mon modèle sans argument, ça se fait à votre avis?

Reply

Marsh Posté le 29-05-2009 à 15:06:06    

On peut changer ce que l'on veut.
Mais, le passage du nom de fichier en paramètre est quelque chose de courant et de pratique.

Reply

Marsh Posté le 29-05-2009 à 15:07:46    

olivthill a écrit :

On peut changer ce que l'on veut.
Mais, le passage du nom de fichier en paramètre est quelque chose de courant et de pratique.


 
j'ai essayé mais apparemment le problème ne viens pas de là. je ne sais pas quoi faire.
 
comment je teste argc > 0?
 
en fortran, y a beaucoup plus de détails sur ce qui puisse poser problème dans l'execution, parce que là je suis vraiment bloquée, en plus pour un débutant, c'est encore plus difficile!

Message cité 1 fois
Message édité par lyn24 le 29-05-2009 à 15:14:55
Reply

Marsh Posté le 29-05-2009 à 15:36:27    

olivthill a écrit :

On peut changer ce que l'on veut.
Mais, le passage du nom de fichier en paramètre est quelque chose de courant et de pratique.


 
excuse moi, je sais pas si vous êtes toujours là.
 
je viens de me rendre compte qu'en compilant avec gcc (au lieu de g++), ça me met mille erreur. qu'est ce qui cause ça à votre avis?par exemple:
 
fich1.h:35:11: error: invalid digit "8" in octal constant
fich2.h:17: error: stray '#' in program
main.h:18: error: stray '\351' in program
main.h:47: error: expected identifier or '(' before '/' token
/usr/include/time.h:184: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'clock'
main.h:145: error: missing terminating ' character
fich3.c:150:2: warning: "/*" within comment
 
Pourriez-vous m'aider SVP?

Reply

Marsh Posté le 30-05-2009 à 19:37:56    

lyn24 a écrit :

comment je teste argc > 0?


argc contient le nombre d'arguments de ta ligne de commande y compris le  nom du programme. Exemple: si tu tapes
prog toto titi tata
et que dans le programme "prog" tu affiches argc, tu auras 4 puisque la ligne qui lance le programme comporte 4 mots.
 
Or à un moment donné, tu copies la chaîne argv[1] (sensée contenir l'argument n° 1) dans une variable via strcpy(). Mais si ta ligne de commande n'a pas d'argument n° 1, la variable argv[1] existe mais son contenu est totalement aléatoire (puisqu'une variable n'est jamais vide). Et comme la fonction strcpy() attend quelque chose de bien spécifique, ça foire
 
Donc dans ton main, il te faut faire un test si argc > 1 et demander au programme de ne pas continuer si ce n'est pas le cas via un simple exit(valeur quelconque différente de 0)
 

lyn24 a écrit :

excuse moi, je sais pas si vous êtes toujours là.


 
Oui, eux ou d'autres il y a toujours quelqu'un sur ce fofo...
 

lyn24 a écrit :

je viens de me rendre compte qu'en compilant avec gcc (au lieu de g++), ça me met mille erreur. qu'est ce qui cause ça à votre avis?


Ah GROS PROBLEME !!! On ne compile pas un code C avec un compilo C++ ni un code C++ avec un compilo C.
Le C et le C++ ont de fortes ressemblances (le C++ a hérité de beaucoup de notions du C) mais ce ne sont pas du tout les mêmes langages.
Même si un compilo C++ "peut" arriver à compiler du C très basique (puisque beaucoup de choses C se retrouvent en C++), ça ne se fait pas. C'est comme si tu branchais un appareil 220V sur du 110V. L'appareil sera alimenté... mais ça ne lui fera pas du bien !!!
Donc te faut IMPERATIVEMENT vérifier si ton langage est du C ou du C++. Ensuite, examiner les warnings un à un. Toutefois, certains warnings se trouvent dans des ".h". Si t'es pas l'auteur de ces ".h", ça va être difficile...


Message édité par Sve@r le 30-05-2009 à 19:39:00

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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