erreur de segment de programme du compilateur GCC: concaténation de deux chaînes

Le code suivant segment error de segment error du compilateur GCC :

 char *str1 = "India"; char *str2 = "BIX"; char *str3; str3 = strcat(str1, str2); printf("%s %s\n", str3, str1); 

Le problème est str3=strcat(str1, str2) .

Ma question est donc la suivante: pour GCC Comstackr, il est interdit à deux pointeurs pointant vers la même chose?

Ce que vous auriez dû écrire, en termes de code, répond à votre question:

 char *str1 = "India"; char *str2 = "BIX"; //should have been const char *str1 = "India"; const char *str2 = "BIX"; 

Les variables str1 et str2 se voient atsortingbuer l’adresse en mémoire où se trouvent les chaînes CONSTANTS India et BIX . Cette mémoire est en lecture seule . Vous essayez de concaténer ces deux chaînes à l’aide de strcat . Ok, regarde ce qu’il fait:

 strcat(str1, str2); /\ take this || copy || =========== add to end 

Pour cela, str1 doit pointer sur un bloc de mémoire suffisamment grand pour accueillir à la fois les caractères que vous êtes en train de concaténer. Dans le cas de littéraux de chaîne, ce n’est jamais le cas.
Rappelez-vous également comment j’ai écrit votre code avec le spécificateur de classe de stockage const ? Regardons strcat le prototype de strcat :

 char * strcat(char * destination, const char *source); 

La fonction s’attend à ce que le premier argument soit un caractère ordinaire char * , pas un const. Cela vous indique que la fonction tentera de changer la mémoire sur laquelle pointe le pointeur. Comme d’autres l’ont fait remarquer, et j’ai mentionné ci-dessus: la mémoire sur str1 pointe le pointeur str1 est en lecture seule , d’où le segfault.

Ce que tu pourrais écrire c’est:

 char str1[15] = "India"; const char *str2 = "BIX"; strcat(str1, str2); 

Cela devrait fonctionner. Notez que strcat ne vérifie / empêche pas les débordements. La taille de la mémoire de destination doit être suffisamment grande pour accueillir strlen(source) + strlen(destination) + 1 . Utiliser strncat place serait encore mieux! Il vous permet de spécifier un nombre maximal de caractères à concaténer sur la chaîne de destination:

 size_t free_space = 15; char str1[free_space] = "India"; const char *str2 = "BIX"; free_space -= strlen(str1) + 1;//add 1 here, to ensure we'll have room for the terminating \0 char char *str3 = strncat( str1, str2, free_space ); //now we've concatenated something onto our ssortingng, keep track of free space left: free_space -= strlen(str2);//dangerous, though -> size_t is unsigned, perhaps best do: size_t src_len = strlen(str2); char *str3 = strncat( str1, str2, free_space ); if (src_len >= free_space) free_space = 0; else free_space -= src_len; 

Habituellement, les littéraux de chaîne seront placés dans une région de mémoire en lecture seule, votre appel à strcat() tentera d’écrire dans cette région de mémoire en lecture seule, ce qui entraînera une erreur de segment.

strcat

 char * strcat ( char * destination, const char * source ); 

Concaténer des chaînes Ajoute une copie de la chaîne source à la chaîne de destination. Le caractère nul final dans la destination est remplacé par le premier caractère de la source et un caractère nul est inclus à la fin de la nouvelle chaîne formée par la concaténation des deux dans la destination.

pointeur de destination sur le tableau de destination, qui devrait contenir une chaîne C et être suffisamment grand pour contenir la chaîne résultante concaténée.

Mais votre destination n’est pas un pointeur sur un tableau (qui est assez grande pour contenir la chaîne résultante concaténée), c’est un pointeur sur sting littéral, la raison de l’erreur de segmentation est que vous allez écrire en lecture seule des emplacements mémoire.

Essayer de changer un littéral de chaîne appelle un comportement indéfini. Il est en lecture seule même s’il n’est pas qualifié.

 str3 = strcat(str1, str2); 

La déclaration ci-dessus appelle strcat qui a un prototype

 char *strcat(char *dest, const char *src); 

Ici, dest est un pointeur sur un tampon suffisamment grand pour que la chaîne indiquée par src soit ajoutée à celui-ci. str1 est un pointeur sur un littéral de chaîne. Par conséquent, strcat lira les caractères de la chaîne str2 et les écrira au-delà de la chaîne str1 qui est illégale. Vous n’avez pas besoin de sauvegarder la valeur de retour de strcat dans une variable char * distincte, car celle-ci modifie son premier argument. Ainsi, après le retour de strcat , la chaîne pointée par src est ajoutée à celle pointée par dest . Vous devriez changer votre code en

 #define MAX_SIZE 40 char str1[MAX_SIZE] = "India"; const char *str2 = "BIX"; // str1 must be large enough for // str2 to be appended to it strcat(str1, str2); printf("%s %s\n", str2, str1); 

Tu en as besoin:

 char str1[100] = "India"; // str1 is an array for maximum 100 chars, initialized with "India" char *str2 = "BIX"; // str2 is a pointer to the ssortingng literal "BIX" (read only) char *str3 ; // str3 is pointer to char str3 = strcat(str1, str2); // appends "BIX" to "India" in the str1 buffer and puts str1 in str3 printf("%s %s\n", str3, str1);