Questions pour un malloc sur (char *) et sur (char **)
Résolu
Utilisateur anonyme
-
Utilisateur anonyme -
Utilisateur anonyme -
Bonjour,
Je me posais une question relative aux allocations dynamiques avec les pointeurs sur pointeurs.
Je dois réaliser une fonction prenant en paramètres un
voici son prototype :
Je me posais cependant une question quant aux allocations que je vais devoir effectuer (avec
Si je comprends bien le
Je vais donc au début de ma fonction créer un
Seulement, à chaque fois que je vais ajouter l'adresse d'un
De plus je n'ai le droit qu'aux fonctions
Faire un
Ce qui signifie que je dois faire une copie de ces données pour les réinsérer après avoir agrandi mon
Merci d'avance pour votre aide.
Je me posais une question relative aux allocations dynamiques avec les pointeurs sur pointeurs.
Je dois réaliser une fonction prenant en paramètres un
(char const*)et un
(char), et renvoyant un
(char **).
voici son prototype :
char **ft_strsplit(char const *s, char c)le
(char c)est en fait un élément séparateur que je dois utiliser pour fragmenter le (char const *s) passé en paramètre en une suite de (char *) que contiendra le
(char **)renvoyé.
Je me posais cependant une question quant aux allocations que je vais devoir effectuer (avec
malloc).
Si je comprends bien le
(char **)renvoyé par la fonction contiendra en fait l'ensemble des adresses sur les petits bouts de chaînes extraits du (char const *s).
Je vais donc au début de ma fonction créer un
(char **result)que je renverrai à la fin.
Seulement, à chaque fois que je vais ajouter l'adresse d'un
(char *)à
result, devrai-je lui allouer en plus la taille d'une adresse (d'un pointeur donc) ou la taille du
char *que j'ajoute?
De plus je n'ai le droit qu'aux fonctions
mallocet
free. Ce qui signifie que je ne peux pas utiliser
realloc, je devrai donc en faire l'équivalent.
Faire un
freepuis un
mallocsur un pointeur écrase les données que l'ont avait avec le
malloc?
Ce qui signifie que je dois faire une copie de ces données pour les réinsérer après avoir agrandi mon
result?
Merci d'avance pour votre aide.
A voir également:
- Questions pour un malloc sur (char *) et sur (char **)
- Coco char - Accueil - Réseaux sociaux
- Remplaçant de Coco : quelles solutions pour tchater gratuitement en ligne ? - Accueil - Réseaux sociaux
- Convertir char en int c ✓ - Forum C
- Char(10) excel francais ✓ - Forum Excel
- [C]- convertir char en int ✓ - Forum C
1 réponse
Bonjour,
Pas besoin de realloc(), ni de free() sauf pour la libération des zones mémoires finales.
Je te donne les 3 étapes importantes pour construire ta fonction :
1/ on compte le nombre de séparateur dans la chaîne pour en déduire le nombre de lignes de ton tableau 2d => malloc() sur la première dimension du char**
2/ pour chacune de tes cases, tu comptes le nombre de caractère jusqu'au prochain séparateur pour en déduire la taille de la case du tableau 2d => malloc() sur l'élément courant de ton char **.
3/ Toujours pour chacune de tes cases, tu recopies les caracteres de la chaine dans ton char ** => strncpy() pour spécifier le nombre de caractères à recopier.
Noublie pas une fonction de liberation des zones allouees par malloc().
Et attention pour les malloc(), il ne faut pas oublier le caractère final \0.
Voila tu as assez delements pour créer ta fonction de split().
Cdlt,
Pas besoin de realloc(), ni de free() sauf pour la libération des zones mémoires finales.
Je te donne les 3 étapes importantes pour construire ta fonction :
1/ on compte le nombre de séparateur dans la chaîne pour en déduire le nombre de lignes de ton tableau 2d => malloc() sur la première dimension du char**
2/ pour chacune de tes cases, tu comptes le nombre de caractère jusqu'au prochain séparateur pour en déduire la taille de la case du tableau 2d => malloc() sur l'élément courant de ton char **.
3/ Toujours pour chacune de tes cases, tu recopies les caracteres de la chaine dans ton char ** => strncpy() pour spécifier le nombre de caractères à recopier.
Noublie pas une fonction de liberation des zones allouees par malloc().
Et attention pour les malloc(), il ne faut pas oublier le caractère final \0.
Voila tu as assez delements pour créer ta fonction de split().
Cdlt,
Tout d'abord merci pour ta réponse.
Cependant ce n'est pas un algorithme pour ma fonction que je cherche, je trouverai tout seul sans problème, mais une réponse à cette question que je reformule ici :
La mémoire allouée à mon devra-t-elle être égale à la mémoire prise par les pointeurs (juste les adresses) ou à ce que je pointe avec ces pointeurs?
par exemple si mon result contient :
on aura et
seulement voilà :
La taille de result sera-t-elle égale à la taille de deux adresses (s1 + s2), ou à la taille de la chaîne commençant à s1 plus la taille de la chaîne commençant à s2?
J'ai juste besoin de cette info :) Si fais comme on me dit de faire je réaliserai peut-être la fonction sans avoir besoin d'apprendre d'avantage, mais je cherche justement à en apprendre d'avantage en me confrontant à ce problème, pas en le contournant. ;)
Mais merci!
Ok, mais vu que tu me semblais partir dans la mauvaise direction au vu de tes explications, j'ai préféré rectifier le tir...
On aura result[1] = s1; et result[2] = s2;
Non. Il faut plutôt recopier les données.
La taille de result sera-t-elle égale à la taille de deux adresses (s1 + s2), ou à la taille de la chaîne commençant à s1 plus la taille de la chaîne commençant à s2?
Ben j'y réponds dans mon post... Partie 1, je dis que c'est en fonction du nombre de séparateurs. Entre les séparateurs se sont des chaînes, donc, la taille de result doit être égale au nombre de chaînes (ici 2) multiplié par la taille d'un pointeur (sizeof char*).
J'avais mal compris.
" la taille de result doit être égale au nombre de chaînes (ici 2) multiplié par la taille d'un pointeur (sizeof char*)."
C'est tout ce que je cherchais à savoir pour cette question-ci. Merci :)
Je peux faire comme tu dis mais je compterais alors plutôt le nombre de sous-chaînes :
Il peut y avoir plusieurs séparateurs accolés et il peut aussi y en avoir (ou non) en début et en fin de chaîne.
Par contre je ne pense pas que ma méthode soit mauvaise, plus compliquée à la rigueur.
Mais j'ai des contraintes au niveau des fonctions permises, et au niveau du volume de lignes de code.
De toute façon j'avais besoin d'éclaircir ce point. :) Grand merci.
Et sinon, le fait de free(), puis de refaire un malloc() sur un pointeur conserve-t-il les données?
à priori je dirais "pas forcément" puisque le malloc n'allouera pas forcément le même emplacement en mémoire, je me trompe?
Ben, s'il y a plusieurs séparateurs accolés, il faut les compter et créer des chaînes vides. Le nombre de sous-chaînes est donc lié au nombre de séparateurs.
Par contre je ne pense pas que ma méthode soit mauvaise, plus compliquée à la rigueur.
Si tu parles de result[1] = s1; et result[2] = s2; , ce n'est pas plus compliqué, au contraire. Mais c'est surtout impossible. Il ne faut pas oublier de ce que j'ai compris à ton énoncé que ta chaîne vaudra ch="coucou|ceci|est|un|test". Donc si tu fais result|0]=ch; tu récupéreras toute la chaîne (le séparateur n'est pas un '\0'). Et puis dès lors que ch sera modifié, result sera modifié...
Et sinon, le fait de free(), puis de refaire un malloc() sur un pointeur conserve-t-il les données?
Oui, les données sont conservées dans le heap. Mais malloc() ne pointera pas forcément vers le début de la zone.
puisque le malloc n'allouera pas forcément le même emplacement en mémoire
C'est, exactement ça. Mais pour ton exercice, tu n'as pas besoin de faire de malloc() après ton free().
J'ai tout de même finalement choisit de partir sur ce genre de méthode, c'est plus simple au final. J'ai fait comme ceci pour calculer la taille du (char **) :
Je pense pouvoir me débrouiller pour la suite, merci :)