strtok et les fuites de mémoire
J'ai écrit une url simple analyseur à l'aide de strtok(). voici le code
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *protocol;
char *host;
int port;
char *path;
} aUrl;
void parse_url(char *url, aUrl *ret) {
printf("Parsing %s\n", url);
char *tmp = (char *)_strdup(url);
//char *protocol, *host, *port, *path;
int len = 0;
//protocol agora eh por exemplo http: ou https:
ret->protocol = (char *) strtok(tmp, "/");
len = strlen(ret->protocol) + 2;
ret->host = (char *) strtok(NULL, "/");
len += strlen(ret->host);
//printf("char at %d => %c", len, url[len]);
ret->path = (char *)_strdup(&url[len]);
ret->path = (char *) strtok(ret->path, "#");
ret->protocol = (char *) strtok(ret->protocol, ":");
//host agora é por exemplo address.com:8080
//tmp = (char *)_strdup(host);
//strtok(tmp, ":");
ret->host = (char *) strtok(ret->host, ":");
tmp = (char *) strtok(NULL, ":");
if(tmp == NULL) {
if(strcmp(ret->protocol, "http") == 0) {
ret->port = 80;
} else if(strcmp(ret->protocol, "https") == 0) {
ret->port = 443;
}
} else {
ret->port = atoi(tmp);
}
//host = (char *) strtok(NULL, "/");
}
/*
*
*/
int main(int argc, char** argv) {
printf("hello moto\n");
aUrl myUrl;
parse_url("http://teste.com/Teste/asdf#coisa", &myUrl);
printf("protocol is %s\nhost is %s\nport is %d\npath is %s\n", myUrl.protocol, myUrl.host, myUrl.port, myUrl.path);
return (EXIT_SUCCESS);
}
Comme vous pouvez le voir, j'ai utiliser strtok() beaucoup donc je peux "tranche" de l'url. Je n'ai pas besoin de soutien url différente de l'adresse http ou https donc, la façon dont c'est fait résout tous mes problèmes.
Mon souci c'est que (c'est en cours d'exécution sur un dispositif intégré) - Suis-je perdre la mémoire ?
Quand j'écris quelque chose comme
ret->protocol = (char *) strtok(tmp, "/");
Et puis plus tard, appelez
ret->protocol = (char *) strtok(ret->protocol, ":");
Ne m'premier pointeur ret->protocole de détenus restent en mémoire ? J'ai pensé que je devrais peut-être mis du premier appel à la tmp pointeur, appel strtok pointant ret->protocole sur la partie droite de la chaîne (le deuxième appel) et puis free(tmp).
Ce que devrait être la meilleure façon d'utiliser strtok ?
OriginalL'auteur guigouz | 2009-09-29
Vous devez vous connecter pour publier un commentaire.
Pour répondre directement à votre question, strtok seulement retourne un pointeur vers un emplacement à l'intérieur de la chaîne de vous la donner en entrée, il ne faut pas allouer la mémoire nouveau pour vous, donc n'a pas besoin d'appeler gratuitement sur des pointeurs, il vous donne en retour.
Pour ce que ça vaut, vous pouvez également regarder dans "strchr" et "strstr", qui sont non destructifs, des moyens de recherche de caractères simples ou des séquences dans les cordes.
Notez également que votre allocation de mémoire est problématique ici, vous êtes à l'aide de strdup() pour allouer une nouvelle corde à l'intérieur de votre fonction d'analyse, et puis vous êtes l'attribution des fragments de bloc de mémoire à des champs de "ret". Votre interlocuteur va donc être responsable de libre avec le strdup avais de la chaîne, mais puisque vous êtes seulement de passage cette chaîne implicitement à l'intérieur de ret, l'appelant a besoin de savoir comme par magie ce que le pointeur de passer gratuit. (Probablement ret->protocole, mais peut-être pas, selon la façon dont l'entrée ressemble.)
OriginalL'auteur Ben Zotto
strtok modifie la corde en place, en remplaçant les caractères spécifié avec la valeur NULL. Puisque les chaînes de caractères en C sont NUL, il apparaît aujourd'hui que l'original de votre pointeur pointe vers une chaîne plus courte, même si la chaîne d'origine est toujours là et occupe toujours la même quantité de mémoire (mais avec des personnages remplacé par la valeur NULL). La fin de la chaîne, je pense, contient un double-NULLES.
La réponse est simple: Garder un pointeur sur le début de votre tampon de chaîne, et une autre pointeur qui est votre "courant" pointeur dans la chaîne comme vous l'analyser. Lorsque vous utilisez strtok ou effectuer une itération sur la chaîne a d'autres façons de mettre à jour le "courant" pointeur mais laissez le pointeur de début seul. Lorsque vous avez terminé, free() au début du pointeur. Pas de fuite de mémoire.
OriginalL'auteur Whiteknight
Savez-vous que vous pouvez continuer l'analyse de la chaîne à l'aide de la valeur NULL comme premier paramètre de strtok?
Premier appel:
Alors:
Cette option vous permet de simplifier votre code:
Vous pouvez le voir j'ai eu un retour de la valeur à savoir si l'analyse a été réalisé avec succès.
OriginalL'auteur Patrice Bernassola
Merci pour le partage de votre code! J'ai couru à l'intérieur de valgrind et fixe deux fuites de mémoire générée par strdup fonctions.
OriginalL'auteur arreche