Erreur de segmentation
safadoo
-
Hxyp Messages postés 401 Date d'inscription Statut Membre Dernière intervention -
Hxyp Messages postés 401 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
j'explique mon problème , mon probleme a pour but de recevoir (etant un serveur tcp) des trames Gcode par exemple "G21 G90 G00 X100 Y150 Z120 " et je dois les traduire et les mettre dans une trames , pour cela j'utilise strtok qui scinder la trames a chaque espace tout ca dans une boucle, il fati 2 fois la boucle mais a la troisième fois il entre dans le test de G00 ( car a chaque isolement il regarde ce qu'il y a dans le pointeur recu apr strtok) et il doit la isoler les coordonnées mais j'ai cette erreur de segementation que je ne comprend pas bref voici mon programme :
et il affiche donc ca :
j'ai tester dans le debug mais sa aide pas bcp :
Program received signal SIGSEGV, Segmentation fault.
0xb7f65df4 in ?? () from /lib/i386-linux-gnu/libc.so.6
j'explique mon problème , mon probleme a pour but de recevoir (etant un serveur tcp) des trames Gcode par exemple "G21 G90 G00 X100 Y150 Z120 " et je dois les traduire et les mettre dans une trames , pour cela j'utilise strtok qui scinder la trames a chaque espace tout ca dans une boucle, il fati 2 fois la boucle mais a la troisième fois il entre dans le test de G00 ( car a chaque isolement il regarde ce qu'il y a dans le pointeur recu apr strtok) et il doit la isoler les coordonnées mais j'ai cette erreur de segementation que je ne comprend pas bref voici mon programme :
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h> #include "string.h" #include "charlyrobot.h" #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 #define PORT 5000 #define TRUE 1 /* Creation d'un type bool */ #define FALSE 0 typedef int SOCKET; typedef struct sockaddr_in SOCKADDR_IN; typedef struct sockaddr SOCKADDR; int main(){ int first_time = TRUE; char connectee[20] = "Connexion etablie"; char *pointeur,*pointeur_tmp,*pointeur_while; char *cp_buffer_reception,*buffer_envoie; int get_out = 0; /* Socket et adressage du serveur */ int i = 0, X_int = 0, Y_int = 0, Z_int = 0; char *X_char = NULL, *Y_char = NULL, *Z_char = NULL; int absolu,pouce; int taille; SOCKET sock; SOCKADDR_IN sin; socklen_t size = sizeof(sin); /* Taille de l'adresse */ char buffer_reception[40] =""; /* Socket et adressage du client */ SOCKET csock; SOCKADDR_IN csin; socklen_t csize = sizeof(sin); /* Taille de l'adresse */ if( (sock = socket( AF_INET, SOCK_STREAM, 0) ) != INVALID_SOCKET ){ printf("Ouverture socket en mode TCP/IP \n"); /********************************* Configuration de la connexion ***********************************************/ sin.sin_addr.s_addr = htonl(INADDR_ANY); /* Adresse IP auto */ sin.sin_family = AF_INET; sin.sin_port = htons(PORT); /* Port definie 5000 */ printf("Ouverture du port %d \n\n",PORT); /*********************************************** Etablissement de la connexion *********************************/ if( (bind(sock, (SOCKADDR*)&sin, sizeof(sin) ) ) != SOCKET_ERROR){ /******************** ***********On met la socket en état d'écoute *********************************************/ if( (listen(sock,1) ) != SOCKET_ERROR ){ /******************************* On attend que le client se connecteee *******************************************/ csock = accept(sock, (SOCKADDR*)&csin, &csize ); send(csock, connectee, sizeof(connectee), 0); /* Envoie chaine "caractère envoyé" pour tester la connexion du client au serveur */ if( (recv( csock, buffer_reception, sizeof(buffer_reception), 0 ) ) != SOCKET_ERROR ){ printf("Connexion client socket %d de %s : %d \n",csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port) ); printf("Buffer recue :"); for( i = 0; i < sizeof(buffer_reception) ; i++){ printf( " %c",buffer_reception[i]); } printf("\n"); while(get_out == 0){ /**************************************** Puis on recoit les données du client *********************************/ /* On copie le contenu de buffer_reception */ cp_buffer_reception = strdup(buffer_reception); if(cp_buffer_reception == NULL ){ printf("erreur copie buffer\n"); exit(-1); } /* On separe et analyse les données recus pour pouvoir les analysés séparement */ /*On utilise la méthode strtok pour isoler les différentes méthode et coordonnée*/ /* Premier appel de strtok */ if(first_time == TRUE ){ printf("rentrer dans first time vrai\n"); pointeur = strtok( cp_buffer_reception, " " ); first_time = 0; } /* puis on cherche les autres séparateur */ else if(first_time == FALSE){ printf("rentrer dans first time faux \n"); pointeur = strtok( NULL , " " ); } printf("pointeur:%s\n",pointeur); /************************************************** Test du buffer recu *******************************************************/ if( strcmp( pointeur,"G20" ) == 0 ){ printf("Programmation en pouce\n"); /* On utilise l'unité de mesure pouce, sauf si on rencontre G21 */ /* On utilise un bool qui defini si les coordonnées sont en pouce ou mm, ici pouce vaut TRUE */ pouce = 1; /*1 = TRUE */ } if( strcmp ( pointeur,"G21" ) == 0 ){ printf("Programmation en mm\n\n"); /* On utilise l'unité de mesure mm, sauf si on rencontre G20 */ /* On utilise un bool qui defini si les coordonnées sont en pouce ou mm, ici pouce vaut FALSE */ pouce = 0; /*0 = FALSE */ } if( strcmp ( pointeur,"G90" ) == 0 ){ printf("Déplacement en mode absolue donc @0M \n"); /* On utilise que la méthode @0M, sauf si on rencontre G91 */ /* On utilise un bool qui definit si la méthode est absolue ou relative, ici absolue vaut TRUE */ absolu = 1; } if( strcmp ( pointeur,"G91" ) == 0 ){ printf("Déplacement en mode relatif donc @0A \n"); /* On utilise que la méthode @0M, sauf si on rencontre G90 */ /* On utilise un bool qui definit si la méthode est absolue ou relative, ici absolue vaut FALSE */ absolu = 0; } if( strcmp ( pointeur,"G28" ) == 0 ){ printf(" POM \n"); POM(); } if( strcmp ( pointeur,"G00" ) == 0 ){ /* Lecture des coordonnées */ printf("juste avant while \n"); while( pointeur != NULL){ printf("test while"); pointeur = strtok( NULL ," "); //taille = strlen(pointeur); /*On calcule la taille des données contenu dans pointeur */ pointeur_tmp = strndup(pointeur+1,taille-1); /*On copie le contenu a partir des coordonnées */ /* On lit les coordonnées de déplacement */ if( pointeur == 'X' ){ X_int = atoi(pointeur_tmp); } else if( pointeur == 'Y' ){ Y_int = atoi(pointeur_tmp); } else if( pointeur == 'Z' ){ Z_int = atoi(pointeur_tmp); } } if(pouce == TRUE ){ X_int = X_int * 100; Y_int = Y_int * 100; /*On convertie les coordonnées en pas du charlyrobot */ Z_int = Z_int * 100; } else{ X_int = X_int * 25.4 * 100; Y_int = Y_int * 25.4 * 100; Z_int = Z_int * 25.4 * 100; } sprintf(X_char,"%d",X_int); sprintf(Y_char,"%d",Y_int); sprintf(Z_char,"%d",Z_int); /* ******************************** Création de "chaine entrante" pour la fonction mouvement *******************************/ /* On entre la méthode */ if(absolu == TRUE ){ /* On ajoute "@0M" au buffer_envoie */ buffer_envoie = "@0M " ; } else{ /* On ajoute "@0A" au buffer_envoie */ buffer_envoie = "@0A " ; } /* Puis les coordonnées et la vitesse */ /* X */ if( X_char != NULL ){ strcat(buffer_envoie," "); strcat(buffer_envoie,X_char); } else{ strcat(buffer_envoie," 0"); } /* Ajout de la vitesse */ strcat(buffer_envoie," 1000"); /* Y */ if( Y_char != NULL){ strcat(buffer_envoie," "); strcat(buffer_envoie,Z_char); } else{ strcat(buffer_envoie," 0"); } /* Ajout de la vitesse */ strcat(buffer_envoie," 1000"); /* Z */ if( Z_char != NULL){ strcat(buffer_envoie," "); strcat(buffer_envoie,Z_char); } else{ strcat(buffer_envoie," "); strcat(buffer_envoie,"0"); } /* Ajout de la vitesse */ strcat(buffer_envoie," 1000"); printf("Chaine envoyé :%s \n",buffer_envoie); Mouvement(buffer_envoie); } if( strcmp ( pointeur,"G01" ) == 0 ){ /* TODO Lecture de coordonnées */ } if( strcmp ( pointeur,"M2" ) == 0 ){ printf("End of program !\n"); get_out = TRUE; } } /* Fin du while */ } else{ printf("erreur revc !\n"); } } else{ printf("Erreur listen !\n"); } } else{ printf("Erreur bind !\n"); } /* On ferme les sockets client et serveur */ printf("Fermeture des sockets client et serveur \n"); close(csock); close(sock); } else{ printf("Erreur socket !\n"); } return EXIT_SUCCESS; }
et il affiche donc ca :
michel@michel:~/Dropbox/Projet 2013 (1)/Source Mickaël$ ./STRATO Ouverture socket en mode TCP/IP Ouverture du port 5000 Connexion client socket 4 de 127.0.0.1 : 44884 Buffer recue : G 2 1 G 9 0 G 0 0 X 1 0 0 Y 1 5 rentrer dans first time vrai pointeur:G21 Programmation en mm rentrer dans first time faux pointeur:G90 Déplacement en mode absolue donc @0M rentrer dans first time faux pointeur:G00 juste avant while Erreur de segmentation (core dumped)
j'ai tester dans le debug mais sa aide pas bcp :
Program received signal SIGSEGV, Segmentation fault.
0xb7f65df4 in ?? () from /lib/i386-linux-gnu/libc.so.6
A voir également:
- Erreur de segmentation
- Erreur 0x80070643 - Accueil - Windows
- Erreur 4201 france tv ✓ - Forum Réseaux sociaux
- J'aime par erreur facebook notification - Forum Facebook
- Code erreur f3500-31 ✓ - Forum Bbox Bouygues
- Comment recuperer whatsapp supprimé par erreur - Guide
1 réponse
Bonjour,
Il y a plusieurs problèmes déjà remplacez la boucle while par ça :
ensuite il y aura un problème avec les sprintf qui suivent car vous n'allouez pas la mémoire alors que ce ne sont que des pointeurs il faudra alors changer les variables : char *X_char, *Y_char, *Z_char;
par un truc du genre :
char X_char[8],Y_char[8],Z_char[8];
il y aura un autre problème avec buffer_envoie, les strcat n'allouent pas plus de mémoire que sprintf et buffer_envoie n'est qu'un pointeur donc le modifier par, par exemple :
char buffer_envoie[4096];
qui permettra aussi à strcat de fonctionner par la même.
Et il vous faudra modifier les lignes du genre :
ça on ne peut pas le faire après la déclaration d'un pointeur/tableau seulement pendant la déclaration qu'on le peut, bref pouvez utiliser strcpy qui existe pour ce genre de truc :
Après reste un problème dans la façon dont vous vérifiez :
alors que juste au dessus le if avec G00 et le strtok met la var pointeur à NULL enfin faut remanier un peu tout ça.
Edit: pour trouver la ligne qui fait planter le programme compiler avec l'option -g de gcc,
par exemple si le programme se trouve dans main.c, utilisez :
gcc -g main.c -o main
ensuite ne lancez par le programme de cette façon :
./main
mais utiliser le debugger gdb, faites ainsi :
gdb main
puis lorsque gdb est lancé envoyez la commande "run" ou le raccourci "r" :
r
gdb va lancer le programme et quand ça plante il donne de l'info, vous pouvez utiliser la commande "backtrace" ou le raccourci "bt" pour remonter le problème :
bt
Il y a plusieurs problèmes déjà remplacez la boucle while par ça :
printf("juste avant while \n"); pointeur = strtok(NULL," "); while(pointeur!=NULL){ printf(test while\n"); pointeur_tmp=pointeur; if(*pointeur_tmp=='X') X_int=atoi(++pointeur); else if(*pointeur_tmp=='Y') Y_int=atoi(++pointeur); else if(*pointeur_tmp=='Z') X_int=atoi(++pointeur); pointeur=strtok(NULL," "); }
ensuite il y aura un problème avec les sprintf qui suivent car vous n'allouez pas la mémoire alors que ce ne sont que des pointeurs il faudra alors changer les variables : char *X_char, *Y_char, *Z_char;
par un truc du genre :
char X_char[8],Y_char[8],Z_char[8];
il y aura un autre problème avec buffer_envoie, les strcat n'allouent pas plus de mémoire que sprintf et buffer_envoie n'est qu'un pointeur donc le modifier par, par exemple :
char buffer_envoie[4096];
qui permettra aussi à strcat de fonctionner par la même.
Et il vous faudra modifier les lignes du genre :
buffer_envoie = "@0M " ;
ça on ne peut pas le faire après la déclaration d'un pointeur/tableau seulement pendant la déclaration qu'on le peut, bref pouvez utiliser strcpy qui existe pour ce genre de truc :
strcpy(buffer_envoie,"@0M");
Après reste un problème dans la façon dont vous vérifiez :
if( strcmp ( pointeur,"G01" ) == 0 ){
alors que juste au dessus le if avec G00 et le strtok met la var pointeur à NULL enfin faut remanier un peu tout ça.
Edit: pour trouver la ligne qui fait planter le programme compiler avec l'option -g de gcc,
par exemple si le programme se trouve dans main.c, utilisez :
gcc -g main.c -o main
ensuite ne lancez par le programme de cette façon :
./main
mais utiliser le debugger gdb, faites ainsi :
gdb main
puis lorsque gdb est lancé envoyez la commande "run" ou le raccourci "r" :
r
gdb va lancer le programme et quand ça plante il donne de l'info, vous pouvez utiliser la commande "backtrace" ou le raccourci "bt" pour remonter le problème :
bt