J'ai du mal à essayer d'implémenter une fonction Strcpy personnalisée qui est censée gérer les cas où la chaîne SRC est supérieure à la chaîne de destination. Ici, j'ai fourni du code afin que vous puissiez voir toute la fonction. Mon problème est que chaque fois que j'y incrément * devt, il va dans une adresse nulle malgré le fait que j'ai également attribué une mémoire pour correspondre à tout SRC. Cela provoque la défaillance de la segmentation dans (double pointeur) DEST = * SRC. Dest est stocké comme un char * ** parce que, en réalité, l'argument qui doit être passé est une autre chaîne qui est éventuellement de taille plus petite que SRC, et je souhaite écraser * Dest aussi en toute sécurité que possible.
int customStrCpy(char** dest, char* src){ int strlen1 = strlen(*dest), strlen2 = strlen(src); if(strlen1 < strlen2){ //Creates a dynamically allocated array that is big enough to store the contents of line2. *dest = calloc(strlen2, sizeof(char)); char* backup_str = *dest; int copy_arrs; for(copy_arrs = 0; copy_arrs < strlen2; copy_arrs++){ **dest = *src; *dest++; src++; } *dest = backup_str; } else strcpy(*dest, src); }
3 Réponses :
(*dest)++;
Si vous incrémentez le pointeur que Dest code> pointe vers, alors l'appelant n'obtiendra pas un pointeur au début de la chaîne retournée, ils auront un pointeur à la fin de celui-ci.
La bonne solution consiste à utiliser une variable locale pour cela, pas le pointeur de l'appelant. Ou juste appeler strcpy () code>.
Il semblait vouloir qu'il pointit à la fin de la chaîne; Mais oui dans le commentaire, il dit quelque chose de différent.
En fait, non, vous vous trompez. C'est ce que Backup_str.
Oups, n'a pas remarqué cela. Si vous modifiez votre réponse, je peux désvoyer.
Vous devez ajouter Il n'y a pas non plus besoin de la 1 code> à la longueur de la chaîne, pour autoriser le terminateur NULL, et vous devez libérer l'ancien contenu de
DEST code> si vous allociez une nouvelle chaîne. Après cela, vous pouvez faire le même
strcpy () code> comme vous n'avez pas besoin de réaffecter.
int code> retour Type (sauf si vous souhaitez ajouter une erreur d'erreur à
MALLOC () code> et renvoyer un résultat d'état). Cette fonction modifie un argument, il devrait être
void code>. P>
Maintenant, nous devons juste retourner quelque chose d'utile ... aussi, Strcpy () code> quand vous savoir i> la longueur?
Il y a peu de choses gagnées d'utiliser strncpy () code>, puisque vous savez que cela va correspondre. Pourrait utiliser
memcpy () code>. Je ne vais pas m'inquiéter à ce sujet.
void code> ou
int code> est illogique. En utilisant SHLEN pour déterminer s'il y a suffisamment d'espace également - la chaîne de destination pourrait être modifiée à plusieurs reprises avant l'appel.
@P__JJ__ Je ne remets pas en question la prémisse de base de la question.
@Barmar J'ai essayé d'utiliser Memcpy, Strcpy, Strncpy, etc. Tous ont tous complètement foutu les cordes lorsque vous essayez de copier des chaînes plus grandes en plus petites, à la fois la destination et les chaînes de source.
@Noobprogrammer bien sûr. Vous devez toujours allouer une nouvelle chaîne d'abord si la destination n'est pas assez grande.
@NOOBPROGREMMER Le problème de base avec votre question est que vous supposez que SHLEN (* Dest) code> est la quantité de mémoire allouée à la destination. Cela pourrait être plus grand, mais il n'y a aucun moyen de savoir avec
SHLEN () code>, afin que vous puissiez réaffecter quand ce n'est pas vraiment nécessaire. Il serait préférable de transmettre la taille de la mémoire tampon de destination en tant que paramètre séparé.
Il n'y a jamais rien à gagner à partir d'utiliser Strncpy () code>, sauf si vous ne voulez pas réellement écrire une chaîne.
@DEduplicator Je viens de supposer que c'est ce que vous faisiez allusion à quand vous avez mentionné connaître la longueur.
Je faisais allusion à memcpy () code>, que vous avez mentionné à la fin de cette note. Je n'ai pas considéré
strncpy () code> comme une alternative viable du tout, car je ne le vois pas comme une fonction de chaîne, bien que strictement parlant, avec une longueur connue, il arrive que l'on puisse bien le mouillir là-bas.
Généralement Strcpy code> renvoie
Char * code> pour "Direct" Utilisez dans d'autres opérations.
char *mysStrCpy(char **dest, const char *src)
{
size_t len = strlen(src);
char *tmpptr;
*dest = malloc(len + 1);
// or *dest = realloc(*dest, len + 1);
if(*dest)
{
tmpptr = *dest;
while(*tmpptr++ = *src++);
}
return *dest;
}
Strlen code> renvoie le numéro un de moins que vous ne le souhaitez. Mind the Terminant
\ 0 code>. Aussi - est
DEST code> toujours pointant vers une chaîne valide lorsqu'elle est transmise à cette fonction?
Strlen (* Dest) Code> ne vous indiquera que le nombre actuel de caractères de * Dest. S'il a été alloué avant l'appel de votre méthode, vous n'avez aucun moyen de savoir combien d'espace a été alloué sans passer aussi de cette longueur dans votre méthode.
Vous vous rendez compte que cette fonction, même après votre réparation, est essentiellement une fuite de mémoire?
Si vous remplacez la chaîne de destination avec une chaîne nouvellement allouée, vous devez également libérer l'allocation d'origine.
Pourquoi ne pas utiliser
strcpy () code> après
calloc () code>? En outre, pourquoi utiliser
calloc () code> au lieu de
masloc () code>, si vous allez le remplacer immédiatement?
Vous venez de réimplémenter La fonction Standard de POSIX
STRUP () CODE> < / a>.
@Andrewhenle non il n'a pas fait.
STRUP () code> ne réutilisera pas une chaîne existante si elle est assez grande.
@Barmar OK, il a créé un dangereux
STRDUP () code> qui pourrait ou non pas de la mémoire. Comme impliqué précédemment ...
@Andrewhenle vrai. Ma réponse montre comment prévenir la fuite.