Modification de chaine passée en paramètre non prise en compte

Fermé
Utilisateur anonyme - Modifié par orinym le 10/12/2013 à 14:46
 Utilisateur anonyme - 10 déc. 2013 à 18:05
Bonjour,

J'ai eu un projet à faire pour mon école, projet que je n'ai pas pu rendre fonctionnel à cause d'un soucis que je n'ai pas réussi à régler.
Ce projet consistait en la réalisation d'une fonction modifiant une chaîne en passant un (char **) en paramètre, or cette modification semble bien avoir eu lieu dans la fonction mais à l'extérieur c'est comme si rien ne s'était passé.
Je crée donc dans mon main de test un (char *) que je nomme str, je passe donc &str en paramètre de la fonction à tester.
Dans la fonction à tester; je commençais par réallouer de la mémoire au char ** passé en paramètre, puis au char * pointé par le char ** précédent.
Dans le prototype de la fonction, le char ** s'appelle line.
J'alloue donc de la mémoire à line, puis à *line

Chose curieuse, je n'arrive pas à utiliser la notation *line[index], même après allocation de mémoire, cette notation entraîne automatiquement un segfault.

Ensuite la copie s'effectue de la manière suivante :
*(*line + index) = *(buffer + index);
(où buffer est un char *)

Bien entendu il y a autour de cela les boucles et instructions nécessaires au bon fonctionnement de la fonction, mais je pense que le problème se situe dans la forme par laquelle je fais la copie.

à la sortie de la fonction; lorsque j'essaie de lire la chaine que je devrais avoir modifié, j'ai un segfault, apparement elle n'a pas du tout été modifiée.

J'aimerais donc comprende d'où vient l'erreur et si possible comment la corriger. J'aimerais aussi comprendre pourquoi j'ai un segfault en utilisant la notation avec les crochets.

BUF_SIZE est défini dans le header get_next_line.h.

Je vous donne cependant à côté de cela la source de la fonction :

#include <stdlib.h>
#include <unistd.h>
#include "get_next_line.h"
#include "libft.h"

static int empty_buf(char **buffer, int size, char **line);

int get_next_line(int const fd, char **line)
{
char *buffer;
int size;
int index;
int counter;

size = 0;
buffer = (char *) malloc(sizeof(char) * BUF_SIZE);
index = update_buf(fd, &buffer, BUF_SIZE);
while (index >= 0)
{
if (index == 0)
{
line = (char **) ft_realloc((void **) line, size, size + BUF_SIZE);
/* ft_realloc augmente la taille en conservant les char déjà entrés */
size = size + BUF_SIZE;
}
/* c'est ici que la copie se fait */
*(*line + size + index - BUF_SIZE) = *(buffer + index);
ft_putchar(*(*line + size + index - BUF_SIZE));
index = update_buf(fd, &buffer, index); /*update_buf renvoie l'index suivant, et met à jour le buffer le cas échéant. */
}
if (index == (- 1) || index == (- 2))
{
counter = 0;
while (*(buffer + counter) != '\n')
counter = counter + 1;
line = (char **) ft_realloc((void **) line, size, size + counter);
counter = empty_buf(&buffer, size, line);
}
return (index + 2);
}

static int empty_buf(char **buffer, int size, char **line)
{
int index;

index = 0;
while (*(*buffer + index) != '\n')
index = index + 1;
line = (char **) ft_realloc((void **) line, size, size + index);
index = 0;
while (*(*buffer + index) != '\n')
{
*(*line + size + index) = *(*buffer + index);
index = index + 1;
}
return (index);
}

int update_buf(const int fd, char **buffer, int index)
{
int counter;
int result;

if (index < BUF_SIZE - 1)
{
return (index + 1);
}
counter = 0;
while (counter < BUF_SIZE)
{
result = read(fd, (char *) (*buffer + counter), 1);
if (*(*buffer + counter) == '\n')
return (- 1);
if (result == 0)
{
*(*buffer + counter) = '\n';
return (- 2);
}
if (result == (- 1))
return (- 3);
counter = counter + 1;
}
ft_putstr(" fub_etadpu ");
return (0);
}

void **ft_realloc(void **ptr, size_t prev_size, size_t size)
{
unsigned char **src;
unsigned char **dst;
int counter;

src = (unsigned char **) ptr;
dst = (unsigned char **) malloc(sizeof(unsigned char) * size);
*dst = (unsigned char *) malloc(sizeof(unsigned char) * size);
counter = 0;
while (counter < (int) prev_size)
{
*(*dst + counter) = *(*src + counter);
counter = counter + 1;
}
return ((void **) dst);
}
!
Je vous remercie par avance pour votre aide

A voir également:

1 réponse

[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié par [Dal] le 10/12/2013 à 16:53
Salut orinym,

C'est sympa de poster ton code, mais c'est un peu touffu. Cela serait mieux de cerner le problème et de poster juste ce qu'il faut de code pour montrer ton problème.

A ce propos, stp, dis ce que tu mets exactement dans ton main pour faire un test mettant en évidence le problème, qu'est-ce que tu mets en entrée, et qu'est-ce que tu attends en sortie ?

Bref, fais nous un main de test.


Dal
0
Utilisateur anonyme
10 déc. 2013 à 18:05
Bonsoir,

J'ai mis le code, mais j'ai donné des indications sur la nature probable du soucis plus haut.

J'ai également eu l'avis d'un camarade.

Pour le problème de segfault avec les crochets, il faut apparemment utiliser la notation
(*line)[index]
et non pas la notation
*line[index]
(équivalente apparemment à
*(line[index])
)

En ce qui concerne le fait que le str passé en paramètre n'est pas modifié, il semblerait que le problème vienne du malloc sur l'adresse de str, puis sur ce qui est pointé par cette adresse, et non juste sur ce qui est contenu dans cette adresse (le char *).

Cette fonction est censée lire une ligne contenue dans un fichier et en mettre le contenu dans le char * dont l'adresse est passée en paramètre, puis retourner un entier parmi 1, -1, ou 0, selon le succès ou l'échec de la lecture, et l'arrivée en fin de fichier.

Je dois donc avoir dans mon char * (dont je passe l'adresse en paramètre) le contenu d'une ligne d'un fichier (dont le file descriptor est également passé en paramètre) une fois que la fonction a fait son boulot.

Seulement le char * est toujours vide après le passage de la fonction. NULL même!

La lecture du char * dans le main je la fait avec printf ou avec une fonction maison à base de write (j'ai testé avec les deux).

Avec l'aide de mon camarade, j'ai des pistes (cf plus haut) pour essayer de corriger, je vous tiendrai au courant.

Cdt, orinym
0