2013-02-26 4 views
0

J'essaie de faire une fonction qui inverse l'ordre d'une partie d'une chaîne. Je suis nouveau à l'utilisation de pointeurs et pour une raison quelconque, je peux accéder à l'emplacement des caractères de ma chaîne à copier un sous-chaîne, mais je ne peux pas les remettre dans le même endroit ...erreur de segmentation pendant memcpy

Lorsque je tente pour copier la sous-chaîne retournée dans son emplacement d'origine, je reçois

Signal de réception de programme SIGSEGV, Défaut de segmentation. 0x00007ffff7b5dc66 dans ??() from /lib/x86_64-linux-gnu/libc.so.6

Toute aide serait géniale!

Voici ce que j'ai jusqu'à présent:

void reverse(char* line, int start, int end){ 

     char str[end-start]; 

     memcpy (str , line + start , end-start); 

     reverseSubString (str); 

     memcpy (line + start, str , end-start); 

} 

void reverseSubString(char* str){ 

    int i, j, len; 
    char temp; 

    i=j=len=temp=0; 

    len=strlen(str); 

    for (i=0, j=len-1; i<=j; i++, j--) 
    { 
     temp=str[i]; 
     str[i]=str[j]; 
     str[j]=temp; 
    } 
} 
+0

Pourquoi ne pas simplement inverser votre sous-chaîne en place, au lieu de le copier, le renverser et le copier? Passez un argument de longueur à reverseSubString, au lieu d'utiliser strlen (qui est la source de votre bug de toute façon, comme mentionné dans les réponses ci-dessous). –

+0

reverseSubString s'exécute sans problème, mais je vois d'où vous venez. J'ai fait les changements pour incorporer une longueur plus "solide" mais le second memcpy provoque toujours un défaut de segmentation. Je ai d'abord essayé de l'inverser en place était frapper le même problème. – ThomDall

+0

"reverseSubString s'exécute sans problème" - Non, certainement pas ... pas sur une séquence arbitraire de caractères qui ne sont pas terminés par NUL. "Au départ, j'ai essayé de l'inverser en posant le même problème" - alors vous auriez dû essayer de comprendre et de résoudre ce problème, plutôt que d'ajouter des copies inutiles. –

Répondre

3
char str[end-start]; 

    memcpy (str , line + start , end-start); 

À moins que le 0-terminaison de la chaîne d'origine est inclus, vous avez un tableau char qui n'est pas 0 TERMINAISON. Donc

len=strlen(str); 

calcule qui-sait-quoi si cela ne plante pas déjà. Puis

for (i=0, j=len-1; i<=j; i++, j--) 
{ 
    temp=str[i]; 
    str[i]=str[j]; 
    str[j]=temp; 
} 

accède à l'extérieur de la mémoire allouée.

+0

reverseSubString s'exécute sans problème, mais je vois d'où vous venez. J'ai fait les changements pour incorporer une longueur plus "solide" mais le second memcpy provoque toujours un défaut de segmentation. Je ai d'abord essayé de l'inverser en place était frapper le même problème. – ThomDall

+0

Finit ma chaîne était déclarée dans la mémoire non-modifiable! Difficulté facile – ThomDall

1

reverseSubstring() attend une chaîne C terminée par un NUL, parce qu'il appelle strlen() sur la chaîne passée. Cependant, vous ne NUL à la fin de votre chaîne dans la fonction reverse. Soit le faire, ou mieux encore, passer un argument length:

void reverseSubString(char *str, size_t len) 
{ 
    int i, j; 
    char temp; 

    for (i = 0, j = len - 1; i <= j; i++, j--) { 
     temp = str[i]; 
     str[i] = str[j]; 
     str[j] = temp; 
    } 
} 

void reverse(char *line, int start, int end) 
{ 
    char str[end - start]; 
    memcpy(str, line + start, end - start); 
    reverseSubString(str, end - start); 
    memcpy (line + start, str, end - start); 
} 
+0

'reverseSubString (line + start, end-start)' aurait le même effet ... pas besoin de 'memcpy' et de VLA. –

+0

@JimBalter Bien sûr, mais je n'ai pas dit que c'était nécessaire non plus - j'ai juste réparé l'erreur. Pour être honnête, je n'ai même pas pensé à la durée du code (puisque je me suis concentré sur l'erreur). Ce code fonctionne, et le rendre plus rapide n'était pas mon intention, après tout (OP doit aussi s'inquiéter de le faire fonctionner avant d'essayer de le faire rapidement). –

+0

Le fait est qu'il serait bon de souligner que ce code est beaucoup plus complexe et sujet aux erreurs (et inefficace) qu'il ne l'est, plutôt que de l'inclure sans commentaire. En ce qui concerne «le faire fonctionner avant d'essayer de le rendre rapide» - il est beaucoup plus facile de faire du code de travail quand il ne fait pas beaucoup d'opérations inutiles.Il y a une énorme différence entre écrire du code qui est orienté sur le problème, et non seulement être plus simple mais aussi plus efficace, et se tromper avec le code de manière à le rendre plus rapide mais pas orienté problème; Je parlais seulement de l'ancien. –