J'ai un petit problème avec strcat/sprintf notamment en C.
En fait je "parse" un char* caractere par caractere, et je concatene ces
caracteres dans une autre chaine (chaineDest) de caractere char*.
Le probleme est que ma chaine chaineDest, si au depart je lui mets une
taille de 20, et que j'ai besoin ensuite de lui concatener plus de 20
caracteres, comment je fais ?
La solution que j'aurais tendance à utiliser est que quand je vois que
la taille devient trop courte, je sauvegarde ma chaine de caractere
(avec strcpy) chaineDest, je lui realloue la taille qu'il faut avec un
malloc, et je recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille plus grande.
Mais ca me parait abérant de faire ça pour toute concaténation en C ...
J'aime croire que le C n'est pas si barbare qu'on le dit, mais que c'est
plutot parce que je suis plus que juste en C ...
M'est d'avis que c'est une question de conception. Combien de caractères correspondant à ton critère vas-tu récupérer ? La meilleure solution AMA, surtout pour un parsing caractere par caractere est de bien dimensionner sa chaine destination dès le départ (Qst de conception) plutôt que de jouer avec les fonction de gestion de mémoire.
Je parse un fichier contenant des champs séparés par des espaces, je ne peux donc savoir à l'avance quelle taille chaque champ va faire malheureusement !
Voir realloc(). C'est une solution, mais que je préfère réallouer des blocs conséquents, je ne m'amuserais pas a utiliser une telle solution pour rajouter un caractère. Avec realloc(), pas de strcpy a faire (le contenu ne change pas (peut etre tronque si taille demandée plus petite)), tu gardes le bloc précédemment alloué, soit l'agrandissement marche, soit il ne marche pas auqel cas tu gardes le pointeur sur le bloc précédemment alloué.
Je ne me sens pas encore vraiment à l'aise avec cette fonction, je verrai ensuite quand je maitriserai un peu mieux ...
Bah, j'en reviens à la première question, quid du nombre max de caractères correspondant au critère dans la chaine parsée ? Utiliser realloc() est deja bien plus souple que de faire un malloc() du nouveau, un strcpy() puis un free() du precedent mais est-ce vraiment viable dans ton contexte, sachant que realloc demande deja quelques precautions.
J'en reviens à ma première question ;) Je ne connais à priori pas la taille de la chaine parsée ...
Regis
-- Cordialement, Vincent
Targeur fou wrote:
M'est d'avis que c'est une question de conception. Combien de caractères
correspondant à ton critère vas-tu récupérer ? La meilleure solution
AMA, surtout pour un parsing caractere par caractere est de bien
dimensionner sa chaine destination dès le départ (Qst de conception)
plutôt que de jouer avec les fonction de gestion de mémoire.
Je parse un fichier contenant des champs séparés par des espaces, je ne
peux donc savoir à l'avance quelle taille chaque champ va faire
malheureusement !
Voir realloc().
C'est une solution, mais que je préfère réallouer des blocs conséquents,
je ne m'amuserais pas a utiliser une telle solution pour rajouter un
caractère. Avec realloc(), pas de strcpy a faire (le contenu ne change
pas (peut etre tronque si taille demandée plus petite)), tu gardes le
bloc précédemment alloué, soit l'agrandissement marche, soit il ne
marche pas auqel cas tu gardes le pointeur sur le bloc précédemment alloué.
Je ne me sens pas encore vraiment à l'aise avec cette fonction, je
verrai ensuite quand je maitriserai un peu mieux ...
Bah, j'en reviens à la première question, quid du nombre max de
caractères correspondant au critère dans la chaine parsée ?
Utiliser realloc() est deja bien plus souple que de faire un malloc() du
nouveau, un strcpy() puis un free() du precedent mais est-ce vraiment
viable dans ton contexte, sachant que realloc demande deja quelques
precautions.
J'en reviens à ma première question ;) Je ne connais à priori pas la
taille de la chaine parsée ...
M'est d'avis que c'est une question de conception. Combien de caractères correspondant à ton critère vas-tu récupérer ? La meilleure solution AMA, surtout pour un parsing caractere par caractere est de bien dimensionner sa chaine destination dès le départ (Qst de conception) plutôt que de jouer avec les fonction de gestion de mémoire.
Je parse un fichier contenant des champs séparés par des espaces, je ne peux donc savoir à l'avance quelle taille chaque champ va faire malheureusement !
Voir realloc(). C'est une solution, mais que je préfère réallouer des blocs conséquents, je ne m'amuserais pas a utiliser une telle solution pour rajouter un caractère. Avec realloc(), pas de strcpy a faire (le contenu ne change pas (peut etre tronque si taille demandée plus petite)), tu gardes le bloc précédemment alloué, soit l'agrandissement marche, soit il ne marche pas auqel cas tu gardes le pointeur sur le bloc précédemment alloué.
Je ne me sens pas encore vraiment à l'aise avec cette fonction, je verrai ensuite quand je maitriserai un peu mieux ...
Bah, j'en reviens à la première question, quid du nombre max de caractères correspondant au critère dans la chaine parsée ? Utiliser realloc() est deja bien plus souple que de faire un malloc() du nouveau, un strcpy() puis un free() du precedent mais est-ce vraiment viable dans ton contexte, sachant que realloc demande deja quelques precautions.
J'en reviens à ma première question ;) Je ne connais à priori pas la taille de la chaine parsée ...
Regis
-- Cordialement, Vincent
Kinou
Jean-Marc Bourguet wrote:
Kinou writes:
En fait je "parse" un char* caractere par caractere, et je concatene ces caracteres dans une autre chaine (chaineDest) de caractere char*.
Si tu dois recopier tous les caractères d'un intervalle, la solution classique est d'attendre d'avoir atteind la fin de l'intervalle pour faire la copie, comme ça tu connais la taille nécessaire. Ou même de retourner une paire debut de l'intervalle, fin de l'intervalle et de ne faire une copie que si c'est nécessaire.
En effet je pourrais faire ça ! Mais cela m'oblige à faire d'abord n lectures des caracteres pour detecter l'intervalle, et en suite de nouveau n lectures pour les affecter a la nouvelle chaine non ?
Le probleme est que ma chaine chaineDest, si au depart je lui mets une taille de 20, et que j'ai besoin ensuite de lui concatener plus de 20 caracteres, comment je fais ?
La solution que j'aurais tendance à utiliser est que quand je vois que la taille devient trop courte, je sauvegarde ma chaine de caractere (avec strcpy) chaineDest, je lui realloue la taille qu'il faut avec un malloc, et je recopie ensuite dans l'autre sens pour remettre le contenu de ma chaine sauvegardé dans la nouvelle chaine de taille plus grande.
Pourquoi ne commences-tu pas par allouer avec la nouvelle taille, ça copierait une fois de moins. Et naturellement, si tu as beaucoup de concaténation à faire, tu peux allouer plus.
En effet, cf un autre post, je peux économiser une copie comme ca.
A+
-- Cordialement, Vincent
Jean-Marc Bourguet wrote:
Kinou <kinou@animezvous.com> writes:
En fait je "parse" un char* caractere par caractere, et je
concatene ces caracteres dans une autre chaine
(chaineDest) de caractere char*.
Si tu dois recopier tous les caractères d'un intervalle, la
solution classique est d'attendre d'avoir atteind la fin de
l'intervalle pour faire la copie, comme ça tu connais la
taille nécessaire. Ou même de retourner une paire debut de
l'intervalle, fin de l'intervalle et de ne faire une copie
que si c'est nécessaire.
En effet je pourrais faire ça ! Mais cela m'oblige à faire d'abord n
lectures des caracteres pour detecter l'intervalle, et en suite de
nouveau n lectures pour les affecter a la nouvelle chaine non ?
Le probleme est que ma chaine chaineDest, si au depart je
lui mets une taille de 20, et que j'ai besoin ensuite de
lui concatener plus de 20 caracteres, comment je fais ?
La solution que j'aurais tendance à utiliser est que quand
je vois que la taille devient trop courte, je sauvegarde
ma chaine de caractere (avec strcpy) chaineDest, je lui
realloue la taille qu'il faut avec un malloc, et je
recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille
plus grande.
Pourquoi ne commences-tu pas par allouer avec la nouvelle
taille, ça copierait une fois de moins. Et naturellement,
si tu as beaucoup de concaténation à faire, tu peux allouer
plus.
En effet, cf un autre post, je peux économiser une copie comme ca.
En fait je "parse" un char* caractere par caractere, et je concatene ces caracteres dans une autre chaine (chaineDest) de caractere char*.
Si tu dois recopier tous les caractères d'un intervalle, la solution classique est d'attendre d'avoir atteind la fin de l'intervalle pour faire la copie, comme ça tu connais la taille nécessaire. Ou même de retourner une paire debut de l'intervalle, fin de l'intervalle et de ne faire une copie que si c'est nécessaire.
En effet je pourrais faire ça ! Mais cela m'oblige à faire d'abord n lectures des caracteres pour detecter l'intervalle, et en suite de nouveau n lectures pour les affecter a la nouvelle chaine non ?
Le probleme est que ma chaine chaineDest, si au depart je lui mets une taille de 20, et que j'ai besoin ensuite de lui concatener plus de 20 caracteres, comment je fais ?
La solution que j'aurais tendance à utiliser est que quand je vois que la taille devient trop courte, je sauvegarde ma chaine de caractere (avec strcpy) chaineDest, je lui realloue la taille qu'il faut avec un malloc, et je recopie ensuite dans l'autre sens pour remettre le contenu de ma chaine sauvegardé dans la nouvelle chaine de taille plus grande.
Pourquoi ne commences-tu pas par allouer avec la nouvelle taille, ça copierait une fois de moins. Et naturellement, si tu as beaucoup de concaténation à faire, tu peux allouer plus.
En effet, cf un autre post, je peux économiser une copie comme ca.
A+
-- Cordialement, Vincent
Charlie Gordon
"Kinou" wrote in message news:419715c0$0$10709$
En effet après réflexion je n'ai pas besoin de sauvegarder, mais je dois au moins refaire la copie, comme je le fais dans le code si dessous. Ce code intervient lorsque je me rends compte que la place dans line devient trop petite.
Je ne comprends pas la logique des BUFFER_SIZE ici. Ni la soustraction nbBuffer-1 Et il manque au moins un char pour le ' ' final : il faut len+1. Enfin en C sizeof(char) vaut 1 par definition.
tempLine[0]=' ';
Cette ligne est inutile, la destination de strcpy() n'a pas besoin d'être initialisée.
strcpy(tempLine,line);
free(line); line = tempLine; tempLine=NULL;
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
C'est ce qui est assez déconcertant en C au début. On nous demande de gérer ce qui l'était automatiquement (plus au moins efficacement) dans les autres langages.
Oui. Mais l'emploi du passé correspond uniquement à l'ordre dans lequel tu fais l'apprentissage de ces langages, pas l'ordre historique de leur conception. C est antérieur à PHP, Perl, C++, java... Seules des versions primitives et obsolètes de Basic le précèdent. Donc c'est plutot un ancêtre encore relativement vert, et dont on respecte avec humilité les limitations.
Chqrlie.
"Kinou" <kinou@animezvous.com> wrote in message
news:419715c0$0$10709$626a14ce@news.free.fr...
En effet après réflexion je n'ai pas besoin de sauvegarder, mais je dois
au moins refaire la copie, comme je le fais dans le code si dessous. Ce
code intervient lorsque je me rends compte que la place dans line
devient trop petite.
Je ne comprends pas la logique des BUFFER_SIZE ici.
Ni la soustraction nbBuffer-1
Et il manque au moins un char pour le ' ' final : il faut len+1.
Enfin en C sizeof(char) vaut 1 par definition.
tempLine[0]=' ';
Cette ligne est inutile, la destination de strcpy() n'a pas besoin d'être
initialisée.
strcpy(tempLine,line);
free(line);
line = tempLine;
tempLine=NULL;
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
C'est ce qui est assez déconcertant en C au début. On nous demande de
gérer ce qui l'était automatiquement (plus au moins efficacement) dans
les autres langages.
Oui. Mais l'emploi du passé correspond uniquement à l'ordre dans lequel tu fais
l'apprentissage de ces langages, pas l'ordre historique de leur conception. C
est antérieur à PHP, Perl, C++, java... Seules des versions primitives et
obsolètes de Basic le précèdent. Donc c'est plutot un ancêtre encore
relativement vert, et dont on respecte avec humilité les limitations.
En effet après réflexion je n'ai pas besoin de sauvegarder, mais je dois au moins refaire la copie, comme je le fais dans le code si dessous. Ce code intervient lorsque je me rends compte que la place dans line devient trop petite.
Je ne comprends pas la logique des BUFFER_SIZE ici. Ni la soustraction nbBuffer-1 Et il manque au moins un char pour le ' ' final : il faut len+1. Enfin en C sizeof(char) vaut 1 par definition.
tempLine[0]=' ';
Cette ligne est inutile, la destination de strcpy() n'a pas besoin d'être initialisée.
strcpy(tempLine,line);
free(line); line = tempLine; tempLine=NULL;
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
C'est ce qui est assez déconcertant en C au début. On nous demande de gérer ce qui l'était automatiquement (plus au moins efficacement) dans les autres langages.
Oui. Mais l'emploi du passé correspond uniquement à l'ordre dans lequel tu fais l'apprentissage de ces langages, pas l'ordre historique de leur conception. C est antérieur à PHP, Perl, C++, java... Seules des versions primitives et obsolètes de Basic le précèdent. Donc c'est plutot un ancêtre encore relativement vert, et dont on respecte avec humilité les limitations.
Chqrlie.
Emmanuel Delahaye
Charlie Gordon wrote on 14/11/04 :
strcpy(tempLine,line);
free(line); line = tempLine; tempLine=NULL;
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
"C is a sharp tool"
Charlie Gordon wrote on 14/11/04 :
strcpy(tempLine,line);
free(line);
line = tempLine;
tempLine=NULL;
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
Plaît-il ?
-- Chqrlie.
Emmanuel Delahaye
Charlie Gordon wrote on 14/11/04 :
"Emmanuel Delahaye" wrote in message news:
Charlie Gordon wrote on 14/11/04 :
strcpy(tempLine,line);
free(line); /* A */ line = tempLine; /* B */ tempLine=NULL; /* C */
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
Plaît-il ?
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est non NULL) B : Ensuite on met la valeur de tempLine dans line (-> line est toujours non NULL) C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc libéré) ne vaut pas NULL.
Ce qu'il aurait fallu faire:
free(line); tempLine=NULL; line = tempLine;
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
"C is a sharp tool"
Charlie Gordon wrote on 14/11/04 :
"Emmanuel Delahaye" <emdel@YOURBRAnoos.fr> wrote in message
news:mn.73ae7d4b73ee10d6.15512@YOURBRAnoos.fr...
Charlie Gordon wrote on 14/11/04 :
strcpy(tempLine,line);
free(line); /* A */
line = tempLine; /* B */
tempLine=NULL; /* C */
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
Plaît-il ?
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est
non NULL)
B : Ensuite on met la valeur de tempLine dans line (-> line est
toujours non NULL)
C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc
libéré) ne vaut pas NULL.
Ce qu'il aurait fallu faire:
free(line);
tempLine=NULL;
line = tempLine;
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
free(line); /* A */ line = tempLine; /* B */ tempLine=NULL; /* C */
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
Plaît-il ?
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est non NULL) B : Ensuite on met la valeur de tempLine dans line (-> line est toujours non NULL) C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc libéré) ne vaut pas NULL.
Ce qu'il aurait fallu faire:
free(line); tempLine=NULL; line = tempLine;
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
"C is a sharp tool"
Kinou
Emmanuel Delahaye wrote:
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est non NULL) B : Ensuite on met la valeur de tempLine dans line (-> line est toujours non NULL) C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc libéré) ne vaut pas NULL.
Ce qu'il aurait fallu faire:
free(line); tempLine=NULL; line = tempLine;
Relis mon code, je ne dois pas libérer line, car il doit pointer vers la nouvelle chaine de taille plus grande ...
-- Cordialement, Vincent JOUSSE
Emmanuel Delahaye wrote:
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est
non NULL)
B : Ensuite on met la valeur de tempLine dans line (-> line est toujours
non NULL)
C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc
libéré) ne vaut pas NULL.
Ce qu'il aurait fallu faire:
free(line);
tempLine=NULL;
line = tempLine;
Relis mon code, je ne dois pas libérer line, car il doit pointer vers la
nouvelle chaine de taille plus grande ...
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est non NULL) B : Ensuite on met la valeur de tempLine dans line (-> line est toujours non NULL) C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc libéré) ne vaut pas NULL.
Ce qu'il aurait fallu faire:
free(line); tempLine=NULL; line = tempLine;
Relis mon code, je ne dois pas libérer line, car il doit pointer vers la nouvelle chaine de taille plus grande ...
-- Cordialement, Vincent JOUSSE
Charlie Gordon
"Emmanuel Delahaye" wrote in message news:
Charlie Gordon wrote on 14/11/04 :
"Emmanuel Delahaye" wrote in message news:
Charlie Gordon wrote on 14/11/04 :
strcpy(tempLine,line);
free(line); /* A */ line = tempLine; /* B */ tempLine=NULL; /* C */
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
Plaît-il ?
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est non NULL) B : Ensuite on met la valeur de tempLine dans line (-> line est toujours non NULL) C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc libéré) ne vaut pas NULL.
Ce qu'il aurait fallu faire:
free(line); tempLine=NULL; line = tempLine;
Quel pinailleur ! Ma remarque était d'ordre général. Par ailleurs le code me semble plutot faire la reallocation a la main du tableau pointé par line. On peut supposer que line était alloué par malloc, on a alloué un nouveau tableau, copié le contenue de line dedans, libéré line et fait pointer line sur le nouveau tableau. Mettre tempLine à NULL après ça n'est pas particulièrement utile, mais montre un style de programmation défensive que j'aimerais voir plus souvent. Ainsi, je recommande de mettre à NULL les pointeurs sur des blocs qu'on vient de libérer par free(). Ce code n'est pas une illustration de cette recommandation.
Je constate quand même que tu es d'accord avec moi sur l'intérêt de ce type de pratique.
-- Chqrlie
"Emmanuel Delahaye" <emdel@YOURBRAnoos.fr> wrote in message
news:mn.74be7d4bdb5b137e.15512@YOURBRAnoos.fr...
Charlie Gordon wrote on 14/11/04 :
"Emmanuel Delahaye" <emdel@YOURBRAnoos.fr> wrote in message
news:mn.73ae7d4b73ee10d6.15512@YOURBRAnoos.fr...
Charlie Gordon wrote on 14/11/04 :
strcpy(tempLine,line);
free(line); /* A */
line = tempLine; /* B */
tempLine=NULL; /* C */
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
Plaît-il ?
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est
non NULL)
B : Ensuite on met la valeur de tempLine dans line (-> line est
toujours non NULL)
C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc
libéré) ne vaut pas NULL.
Ce qu'il aurait fallu faire:
free(line);
tempLine=NULL;
line = tempLine;
Quel pinailleur !
Ma remarque était d'ordre général.
Par ailleurs le code me semble plutot faire la reallocation a la main du tableau
pointé par line.
On peut supposer que line était alloué par malloc, on a alloué un nouveau
tableau, copié le contenue de line dedans, libéré line et fait pointer line sur
le nouveau tableau. Mettre tempLine à NULL après ça n'est pas particulièrement
utile, mais montre un style de programmation défensive que j'aimerais voir plus
souvent. Ainsi, je recommande de mettre à NULL les pointeurs sur des blocs
qu'on vient de libérer par free(). Ce code n'est pas une illustration de cette
recommandation.
Je constate quand même que tu es d'accord avec moi sur l'intérêt de ce type de
pratique.
free(line); /* A */ line = tempLine; /* B */ tempLine=NULL; /* C */
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
Plaît-il ?
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est non NULL) B : Ensuite on met la valeur de tempLine dans line (-> line est toujours non NULL) C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc libéré) ne vaut pas NULL.
Ce qu'il aurait fallu faire:
free(line); tempLine=NULL; line = tempLine;
Quel pinailleur ! Ma remarque était d'ordre général. Par ailleurs le code me semble plutot faire la reallocation a la main du tableau pointé par line. On peut supposer que line était alloué par malloc, on a alloué un nouveau tableau, copié le contenue de line dedans, libéré line et fait pointer line sur le nouveau tableau. Mettre tempLine à NULL après ça n'est pas particulièrement utile, mais montre un style de programmation défensive que j'aimerais voir plus souvent. Ainsi, je recommande de mettre à NULL les pointeurs sur des blocs qu'on vient de libérer par free(). Ce code n'est pas une illustration de cette recommandation.
Je constate quand même que tu es d'accord avec moi sur l'intérêt de ce type de pratique.
-- Chqrlie
Richard Delorme
strcpy(tempLine,line);
free(line); /* A */ line = tempLine; /* B */ tempLine=NULL; /* C */
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
Plaît-il ?
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est non NULL) B : Ensuite on met la valeur de tempLine dans line (-> line est toujours non NULL) C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc libéré) ne vaut pas NULL.
Tu définis comment « inutilisé ?» line est utilisé, donc il ne faut pas le mettre à NULL. tempLine n'est plus utilisé (sa zone pointée a été reprise par line), donc mis a NULL. Logique, non ?
Ce qu'il aurait fallu faire:
Rappel du contexte : strcpy(tempLine,line);
free(line); tempLine=NULL; line = tempLine;
Après avoir copier line dans tempLine, c'est pas très malin de "nullifier" tempLine...
-- Richard
strcpy(tempLine,line);
free(line); /* A */
line = tempLine; /* B */
tempLine=NULL; /* C */
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
Plaît-il ?
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est
non NULL)
B : Ensuite on met la valeur de tempLine dans line (-> line est toujours
non NULL)
C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc
libéré) ne vaut pas NULL.
Tu définis comment « inutilisé ?»
line est utilisé, donc il ne faut pas le mettre à NULL.
tempLine n'est plus utilisé (sa zone pointée a été reprise par line),
donc mis a NULL.
Logique, non ?
Ce qu'il aurait fallu faire:
Rappel du contexte :
strcpy(tempLine,line);
free(line);
tempLine=NULL;
line = tempLine;
Après avoir copier line dans tempLine, c'est pas très malin de
"nullifier" tempLine...
free(line); /* A */ line = tempLine; /* B */ tempLine=NULL; /* C */
Sage précaution que de nullifier les pointeurs inutilisés ou libérés.
Si c'était vrai... line n'est pas NULL.
Plaît-il ?
A : Ce qui a été libéré, c'est la zone pointée par line. (-> line est non NULL) B : Ensuite on met la valeur de tempLine dans line (-> line est toujours non NULL) C : on met NULL dans tempLine (-> line est toujours non NULL)
"Sage précaution que de nullifier les pointeurs inutilisés ou libérés."
est donc une supposition fausse, car 'line' (qui pointe sur un bloc libéré) ne vaut pas NULL.
Tu définis comment « inutilisé ?» line est utilisé, donc il ne faut pas le mettre à NULL. tempLine n'est plus utilisé (sa zone pointée a été reprise par line), donc mis a NULL. Logique, non ?
Ce qu'il aurait fallu faire:
Rappel du contexte : strcpy(tempLine,line);
free(line); tempLine=NULL; line = tempLine;
Après avoir copier line dans tempLine, c'est pas très malin de "nullifier" tempLine...
-- Richard
David C.
Emmanuel Delahaye avait énoncé :
Ce qu'il aurait fallu faire:
free(line); tempLine=NULL; line = tempLine;
Pas vraiment, on créerait une fuite de mémoire en perdant la notion de la mémoire (allouée par malloc()) pointée par tempLine. Vu l'énoncé de l'OP, le code servait à agrandir une zone de mémoire, pointée par line. Il faut donc bien libérer la mémoire déjà allouée (pointée par line), mettre à jour ce pointeur vers la nouvelle zone de mémoire pointée par tempLine, et subsidiairement nullifier tempLine (pour simplifier la maintenance).
Emmanuel Delahaye avait énoncé :
Ce qu'il aurait fallu faire:
free(line);
tempLine=NULL;
line = tempLine;
Pas vraiment, on créerait une fuite de mémoire en perdant la notion de
la mémoire (allouée par malloc()) pointée par tempLine.
Vu l'énoncé de l'OP, le code servait à agrandir une zone de mémoire,
pointée par line.
Il faut donc bien libérer la mémoire déjà allouée (pointée par line),
mettre à jour ce pointeur vers la nouvelle zone de mémoire pointée par
tempLine, et subsidiairement nullifier tempLine (pour simplifier la
maintenance).
Pas vraiment, on créerait une fuite de mémoire en perdant la notion de la mémoire (allouée par malloc()) pointée par tempLine. Vu l'énoncé de l'OP, le code servait à agrandir une zone de mémoire, pointée par line. Il faut donc bien libérer la mémoire déjà allouée (pointée par line), mettre à jour ce pointeur vers la nouvelle zone de mémoire pointée par tempLine, et subsidiairement nullifier tempLine (pour simplifier la maintenance).