Ce n'est pas vraiment une réponse à la façon dont fonctionne libre, mais je voudrais faire quelque chose le long de ces lignes:
char * trim_realloc (char * str) { char * p = str; char * e; char * ne; // nouvelle fin char * r; size_t len;
// Since you put this level of error testing in your program
if (!str) {
return str; // str is NULL
}
while (*p || isspace(*p)) {
p++;
}
len = strlen(p);
e = p + len;
ne = e;
while (ne > p) {
if (isspace(*ne)) {
*ne = 0;
ne--;
} else {
break;
}
}
if (p == str) {
if (e != ne) {
return realloc(str, len+1); // only tail trim -- you could just return str here
} else {
return str; // no actual trim
}
} else {
r = strdup(p);
free(str); // str is the head of the string, so that's what we have to free
return r;
}
}
Il est à noter mon commentaire sur la ligne avec realloc
Depuis que je remis à zéro l'espace arrière de toute façon (et depuis de nombreuses implémentations de realloc ne vous inquiétez pas à propos de « est-il assez grand », et non « est là aussi beaucoup d'espace supplémentaire ") vous pourriez avoir juste laisser le tampon que votre chaîne a vécu prendre trop de place à la fin. Il est toujours terminé au bon endroit (à moins qu'il y ait des bogues dans mon code non testé, ce qui pourrait être le cas).
D'autres choses que vous pourriez faire serait de déplacer simplement la chaîne au début du tampon, puis couper la queue, de sorte que:
" cat "
est passé par les étapes:
« c chat " "cat ca" "catcat" "chat à" "chat t" "chat"
avant de commencer à couper la queue.
Maintenant, revenons à la façon dont free works - free doit être passé à la valeur NULL ou à la valeur que l'une des fonctions d'allocation de tas vous est passée. Certaines bibliothèques d'allocation de tas sont implémentées de sorte que lorsque malloc alloue des données, la taille de ce bloc de données est stockée dans les octets juste avant l'adresse que retourne malloc, et lorsque vous appelez gratuitement les octets juste en face de ce pointeur sont utilisés pour déterminer la taille de ce morceau de mémoire est réellement. Si vous passez le quelque chose qui n'a pas été retourné par malloc (ou calloc, ou realloc, ou similaire) alors libre peut regarder au mauvais endroit et utiliser tout ce qu'il trouve là comme la taille du morceau que vous libérez - et rien de bon vient de cela.
+1 pour # 3. La fonction spécifiée gère le problème pour le code client, au lieu d'introduire de nouvelles acrobaties. – grossvogel
Il est intéressant de noter que 'memmove()' est utile pour implémenter l'option # 3. – caf