Utilisation de realloc pour concaténer des chaînes

J’essaie de concaténer deux chaînes, en supposant que la chaîne “dest” ne dispose pas de suffisamment d’espace pour en append une autre. J’utilise donc des tableaux dynamics pour le résoudre.

Le problème est une erreur mremap_chunk lors de la tentative de compilation du code.

Je ne sais pas ce qui me manque car l’appel realloc a tous les bons parameters à sa place.


Erreur:

malloc.c:2869: mremap_chunk: Assertion `((size + offset) & (GLRO (dl_pagesize) - 1)) == 0' failed. Aborted (core dumped) 

 #include  #include  #include  char *strcatt(char *s1, char *s2) { int a = strlen(s1); int b = strlen(s2); int i, size_ab = a+b; s1 = (char *) realloc (s1, size_ab*sizeof(char)); for(i=0; i<b; i++) { s1[i+a]=s2[i]; } s1[size_ab]='\0'; return s1; } int main() { char s1[]="12345"; char s2[]="qwerty"; strcatt(s1,s2); printf("%s\n", s1); return 0; } 

Vous ne pouvez pas realloc ou free une mémoire qui n’est pas allouée avec un appel à malloc ou qui n’est pas NULL .

De la section 7.22.3.5. La fonction realloc dans le brouillon C11

La fonction realloc libère l’ancien object pointé par ptr et renvoie un pointeur sur un nouvel object dont la size spécifiée par size. Le contenu du nouvel object doit être identique à celui de l’ancien object avant la désallocation, jusqu’à la plus petite des tailles nouvelles et anciennes. Tous les octets du nouvel object dépassant la taille de l’ancien ont des valeurs indéterminées.

Donc, s1 = (char *) realloc (s1, size_ab*sizeof(char)); est manifestement erroné pour vos entrées (tableaux automatiques), ne faites jamais cela.

Et puis, il y a beaucoup d’autres problèmes qui peuvent être résolus avec l’aide d’un débogueur.

Tout d’abord, vous traitez la mémoire non-tas comme une mémoire tas, ne le faites pas.

Deuxièmement, vous n’incluez pas d’espace pour le terminateur dans le calcul.

Voici quelques points supplémentaires:

  1. Ne nommez pas les fonctions commençant par str , c’est un espace de nom réservé.
  2. Les tailles de mémoire tampon doivent être size_t , pas int .
  3. Ne lancez pas la valeur de retour de malloc() en C.
  4. Utilisez memcpy() pour copier des blocs de mémoire lorsque vous en connaissez la taille.
  5. Les chaînes du “côté droit” doivent être const .
  6. Traiter avec la possibilité d’erreur d’allocation.
  7. Je considère comme une mauvaise pratique d’ sizeof (char) par sizeof (char) , c’est toujours 1.

Voici comment je l’écrirais, en supposant la même logique:

 char * my_strcatt(char *s1, const char *s2) { const size_t a = strlen(s1); const size_T b = strlen(s2); const size_ab = a + b + 1; s1 = realloc(s1, size_ab); memcpy(s1 + a, s2, b + 1); return s1; } 

Le débogueur clang donne une description d’erreur très claire:

 malloc: error for object 0x7fff6fbb16d6: pointer being realloc'd was not allocated set a breakpoint in malloc_error_break to debug 

Vos deux tableaux sont initialisés en tant que littéraux de chaîne. Plus loin, votre fonction essaie de modifier un littéral de chaîne en le réaffectant, ce qui est faux en C standard car vous ne pouvez pas réaffecter ce que vous n’avez pas alloué, puis en copiant les membres du deuxième littéral de chaîne vers “l’object”. destiné à modifier en abusant de realloc() sur un littéral de chaîne.

Le code fonctionnerait si vous aviez défini dynamicment une troisième chaîne dans laquelle vous auriez résumé le contenu des deux:

 #include  #include  #include  char *mystrcatt(char *s1, char *s2) { int a = strlen(s1); int b = strlen(s2); int i, size_ab = a+b; char *s3 = malloc (size_ab*sizeof(char)); //sizeof(char) is always 1 for(i=0; i 

Notez également que vous ne lancez pas le retour de malloc() en C.