2016-11-25 1 views
2
static void foo(unsigned char *cmd) 
    { 
     strcat(cmd, "\r\n"); 
     printf("\r\nfoo: #%s#", cmd); 

    } 
    int main() 
    { 
     foo("test"); 
     return 0; 
    } 

compilateur dit Segmentation fault (core dumped) Quel est le problème réel ici?En utilisant une autre fonction strcat intérieur: Segmentation fault (core dumped)

+2

Vous essayez d'ajouter quelque chose à 'qui ne peut pas être modifié la chaîne littérale' « foo ». C'est un comportement indéfini. –

+2

Je pense que ce n'est pas votre vrai code, c'est juste un bon MCVE. Mais, peut-être dans votre code réel, il n'y a pas de chaîne de caractères impliqués. Quoi qu'il en soit, vous devriez éviter 'strcat()' à moins que, vous avez juste besoin de l'appeler une fois. Construire des chaînes en c peut être fait beaucoup plus efficacement une fois que vous avez vraiment compris comment les piqûres sont représentées dans la langue, et ce qu'elles sont vraiment. –

+1

Sur certaines notes non liées, vous n'avez pas besoin d'utiliser le retour chariot lors de l'impression. Le compilateur s'assurera que la nouvelle ligne est convertie en la séquence correcte pour la plate-forme cible. De plus, la sortie vers 'stdout' (qui est l'endroit où' printf' écrit) est par défaut bufferisée en ligne, donc la sortie est rincée sur newline, ce qui rend la nouvelle ligne principale pratiquement inutile. –

Répondre

6

Vous avez comportement indéfini. Vous n'êtes pas autorisé à modifier littéraux de chaîne. cmd pointe vers un littéral de chaîne et strcat() tente de concaténer, ce qui constitue le problème.

int main(void) 
    { 
     char arr[256] = "test"; 
     foo(arr); 
     return 0; 
    } 

Vous devez généralement être prudent lors de l'utilisation strcpy() et strcat() etc en C comme il y a une possibilité que vous pourriez déborder le tampon. Dans mon exemple, j'ai utilisé une taille de tableau de 256, ce qui est plus que suffisant pour votre exemple. Mais si vous concaténez quelque chose de taille inconnue, vous devez faire attention.

2

Vous essayez d'ajouter quelque chose à la chaîne littérale test qui ne peut pas être modifiée. C'est un comportement indéfini.

Vous voulez ceci:

static void foo(unsigned char *cmd) 
{ 
    strcat(cmd, "\r\n"); 
    printf("\r\nfoo: #%s#", cmd); 
} 

int main() 
{ 
    char test[50] = "test"; 
    foo(test); 
    printf("test after calling foo: %s\n", test); 
    return 0; 
} 
+0

absolument correct @ Michael Walz – suren

2

dans des chaînes C (comme "test") sont en lecture seule des tableaux de caractères. Comme ils sont en lecture seule, ils ne peuvent pas être modifiés. Comme ils sont des tableaux, ils ont une taille fixe. Vous essayez tous les deux de modifier la chaîne littérale et de l'étendre.

1

D'autres personnes ont expliqué pourquoi vous ne pouvez pas effectuer cette opération. Vous avez essentiellement deux options:.

  • Soit vous modifiez la chaîne en place (avec realloc() pour vous permettre d'ajouter votre suffixe ("\r\n") Mais vous devez être prudent et utiliser un malloc données allouées
  • . Sinon, allouer une nouvelle chaîne de la taille de l'entrée, plus la taille de votre suffixe, et copiez la chaîne d'entrée et le préfixe là-bas, et le renvoyer, dans ce cas, l'appelant devra free() la chaîne retournée (et éventuellement celui passé à la fonction, mais cela aurait été traité dans les deux cas)

Éditer: Si vous utilisez un tampon alloué statiquement, vous devrez probablement ajouter un paramètre supplémentaire à la fonction indiquant la taille de la mémoire tampon disponible.

+1

Point 1 est faux, Vous ne pouvez certainement pas 'realloc' une constante de chaîne. Modifiez votre réponse avant qu'elle ne soit réduite. Vous ne pouvez que la mémoire 'realloc' qui a été précédemment allouée par' malloc', 'calloc' et' realloc'. –

+0

@MichaelWalz: Ce que je voulais dire, c'est: je ne connais pas le comportement au moment de l'exécution, en supposant que le compilateur le permette. Merci quand même. – Aif

+1

c'est un comportement indéfini. Le point 1 est toujours trompeur. –

0

Pour travailler avec j'ai changé le programme comme:

static void foo(unsigned char *cmd) 
{ 
    unsigned char local[10]; 
    strcpy(local, cmd); 
    strcat(local, "\r\n"); 
    printf("\r\nfoo: #%s#", local); 

} 
int main() 
{ 
    foo("test"); 
    return 0; 
}