Erreur de segmentation en C

Résolu/Fermé
rocksider Messages postés 106 Date d'inscription mardi 21 octobre 2008 Statut Membre Dernière intervention 16 mars 2012 - 9 nov. 2008 à 15:11
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 9 nov. 2008 à 19:26
Bonjour,
voilà j'ai esseyer de faire le programme qui fait le travaille de strcat, et apres l'avoir compiler quand je l'execute il m'affiche : Erreur de segmentation.

voilàa le code :
#include<stdio.h>
#include<string.h>

char * strcati(char *,char *);

main()
{
char s1,s2;
printf("donner la valeur de s1: ");
scanf("%s",&s1);
printf("donner la valeur de s2: ");
scanf("%s",&s2);
strcati(&s1,&s2);

printf("strcat donne : %s",s1);

}

char * strcati(char s1[],char s2[])
{
char *ps1= s1+(strlen(s1)+1);
char *ps2=s2;
  
while(*ps1++=*ps2++) ;

s2='\0';
return s1;
}

merci d'avance

7 réponses

bizu53 Messages postés 1274 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 21 juin 2015 859
9 nov. 2008 à 15:25
J'ai pas testé, mais ne serait-ce pas ton "while(*ps1++=*ps2++) ;" ?
Un simple égal n'est qu'une affectation, et pas un test d'égalité. Sur des pointeurs ça doit faire de la bonne bouilie dans ton cas lol. (en plus tant que l'affectation se fait bien, ça renvoi 1, et donc ça reste dans ta while)
0
rocksider Messages postés 106 Date d'inscription mardi 21 octobre 2008 Statut Membre Dernière intervention 16 mars 2012 9
9 nov. 2008 à 15:31
oui, il est fait expré le truc de l'affectation, normalement quand ps2++ = '\0' la boucle serait equivalente à while(0) et passerai au instruction suivantes,
0
bizu53 Messages postés 1274 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 21 juin 2015 859 > rocksider Messages postés 106 Date d'inscription mardi 21 octobre 2008 Statut Membre Dernière intervention 16 mars 2012
9 nov. 2008 à 15:39
au temps pour moi, c'est vrai qu'une affectation de 0 renvoie 0.
0
chuka Messages postés 965 Date d'inscription samedi 11 octobre 2008 Statut Membre Dernière intervention 29 juillet 2010 378
9 nov. 2008 à 15:45
Salut,
tu peux essayer ca:
#include<stdio.h>
#include<string.h>

void strcati(char *,char *);

main()
{
char s1[255],s2[255];
printf("donner la valeur de s1: ");
scanf("%s",&s1);
printf("donner la valeur de s2: ");
scanf("%s",&s2);
strcati(s1,s2);
printf("strcat donne : %s",s1);
getchar();
}

void strcati(char* s1,char* s2)
{s1=s1+strlen(s1);
int i=0;
while(*s2!='\0')
{*s1=*s2;
s2++;
s1++;
i++;
}
s1=s1-(strlen(s1)+i-1);
}


autre chose, dans ta fonction initial tu mets une valeur de retour: char* et dans ta fonction main quand tu appelles ta fonction tu n'as pas:
s=strcati(s1, s2)://s etant un char*
si tu fais pas cela, tu n'a pas besoin de faire un return dans ta fonction....et tu fais un void strcati(char s1[],char s2[])
char * strcati(char s1[],char s2[])
{
char *ps1= s1+(strlen(s1)+1);
char *ps2=s2;

while(*ps1++=*ps2++) ;

s2='\0';
return s1;
}
L'erreur segment Fault c'est en général un probleme d'allocation mémoire..
et je t'avouerai que l'exe ne doit pas savoir à quelle adresse correspond cela:char *ps1= s1+(strlen(s1)+1);
A la rigueur:char *ps1=(char*)malloc((strlen(s1)+1)*sizeof(char));
J'espere ca pourra t'aider!!
@+
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
9 nov. 2008 à 16:11
Salut,
Il ne faut pas oublier qu'avec scanf on renvoie l'adresse. Donc dans le cas d'un tableau, il ne faut pas mettre l'esperluette. De plus, scanf n'est pas vraiment conseillé d'utilisation. Préférez-lui fgets par exemple.
#include<stdio.h>
#include<string.h>
void strcati(char *,char *);

int main(void){
    char s1[100],s2[50];
    printf("donner la valeur de s1: ");
    fgets(s1,sizeof(s1),stdin);
    printf("donner la valeur de s2: ");
    fgets(s2,sizeof(s2),stdin);
    strcati(s1,s2);

    printf("strcat donne : %s",s1);
    return 0;

}

void strcati(char s1[],char s2[])
{
    s1=s1+strlen(s1)-1; // -1 si tu veux enlever le \n obtenu lors de la saisi par l'utilisateur
    while(*s1++ = *s2++);
    *s1='\0';
}

Cdlt
0
rocksider Messages postés 106 Date d'inscription mardi 21 octobre 2008 Statut Membre Dernière intervention 16 mars 2012 9
9 nov. 2008 à 16:49
merci a vous fiddy et chukka pour votre aide,merci beaucoup.
bah j'avait les erreurs suivante :
char s1 à la place de char s1[50],
et puis *char à la place de *void,
& devant un tableau dans scanf (meme si n'avait rien changer quand j'ai esseyé)
sinon pourquoi scanf n'est pas tres conseillé ?
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
9 nov. 2008 à 16:59
scanf n'est pas conseillé à cause du peu de protection qu'il offre.
L'utilisateur peut entrer plus de caractères que le maximum et déborder en écriture sur les autres données.
Conséquence : Erreur de segmentation ou pire s'il est "brillamment" exploité.
0

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

Posez votre question
rocksider Messages postés 106 Date d'inscription mardi 21 octobre 2008 Statut Membre Dernière intervention 16 mars 2012 9
9 nov. 2008 à 17:11
Ah oui je me rapelle, il y'a une attaque dont j'ai oublié le nom qui permettait (je me rapelle plus bien ), en tout cas merci bcp :)
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
9 nov. 2008 à 17:12
L'attaque, c'est le buffer overflow (stack ou heap overflow).
Voilà pourquoi c'est important de toujours bien faire attention. C'est ce qui fait du C que c'est assez complexe finalement.
0
bizu53 Messages postés 1274 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 21 juin 2015 859 > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
9 nov. 2008 à 18:26
C'est vrai mais de toute façon cette attaque ne peut être que locale au programme de toute façon, donc il n'y a rien d'extraordinaire à faire avec...

Une autre solution tout en gardant le scanf() sans faire d'overflow est de jouer sur le formatage : scanf("%5s", str); qui prendra que 5 caractères même si plus sont saisis.

Personnellement ce n'est pas pour ce problème là que je n'utilise pas scanf() c'est pour les espaces pour les chaînes de caractères (séparation d'arguments avec scanf(), alors que gets() les prend comme ils le sont : des espaces).
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835 > bizu53 Messages postés 1274 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 21 juin 2015
9 nov. 2008 à 19:26
Oui, mais fgets est quand même bien plus sécurisée. Enfin, le principal est de faire attention au débordement.
Après cette attaque n'est pas forcément locale si l'application développée est serveur.
Et tu dis peu d'intérêt ? J'espère que tu plaisantes, imagine que l'application a les droits setuid, tu te procures un shell sur la machine. Eh hop, élévation des privilèges. Pas pour rien, que les BoF sont d'actualités. Avec le nombre qui en sort par jours, et le fuzzing qui automatise le tout.
Cdlt
0
rocksider Messages postés 106 Date d'inscription mardi 21 octobre 2008 Statut Membre Dernière intervention 16 mars 2012 9
9 nov. 2008 à 18:28
merci :)
0
rocksider Messages postés 106 Date d'inscription mardi 21 octobre 2008 Statut Membre Dernière intervention 16 mars 2012 9
9 nov. 2008 à 18:30
ue j'ai deja travaillé avec les gabarit dans scanf mais c'est vrai j'avais eu le probleme des espace dans le programme meme (celui d'en haut ^^)
0