j'ai une question sur realloc:
$ cat testrealloc.c
#include <stdio.h>
#include <stdlib.h>
int main(void){
char * c=NULL;
c=malloc(8);
if (c == NULL) return -1;
c="abcdefgh";
printf("valeur du pointeur: %d\r\n",c);
printf("valeur de c: %s\r\n",c);
c=realloc(c,16);
return 0;
}
$ gcc -Wall -o testrealloc testrealloc.c
testrealloc.c: In function 'main':
testrealloc.c:9: attention : format '%d' expects type 'int', but argument 2
has type 'char *'
$ ./testrealloc
valeur du pointeur: 134514000
valeur de c: abcdefgh
Erreur de segmentation
Ma question est: pourquoi le realloc segfaulte?
Merci
--
Kevin
Ok. Le malloc n'est pas appelé car la chaine est dans le code du progra mme..
Surtout, le malloc() n'est pas appéléparce que personne ne l'a apelé. En C standard, les apaels à maloc() sont explicites.On est certain que
ni char *s="abcd"; ni char s[]="abcd"; nappelleront malloc().
Il n'y a donc aucun moyen d'utiliser realloc() sur ces chaines.
Par contre, en POSIX, il existe une fonction strdup(), qui, et il FAUT le savoir, utilise malloc().
char *s = strdup("abcd");
on peut donc ensuite agrandir la chaîne comme ceci :
char s2[]="abcdefgh";
s = realloc(s, sizeof s2);
mais la copie de s2 au bout de s n'est pas automatique, il faut ensuite utiliser strcat() :
strcat (s, s2);
en dans tous les cas, libérer s avec free(), quand c'est terminé.
Alexandre Bacquart
On 05/06/2011 10:10 AM, Marc Boyer wrote:
Le 05-05-2011, Alexandre Bacquart a écrit :
Certes, tout ceci est fort joli (et réel)... il y a tellement de façons d'optimiser. Mais ce qui m'intéresse plus particulièrement, c'est la valeur pédagogique de mon propos initial. En quoi mon explication tendrait à mettre le doute dans la tête l'OP, voire à lui inculquer une fausse conception (pour ce qu'il a besoin de savoir pour l'instant) ?
Ayant enseigné le C un certain nombre d'années, j'aurais tendance à dire que ton propos entrainait une confusion, car il supposait que dans l'écriture char str[]= "abdcef"; il y a *deux* objets (str, et "abcdef"), alors qu'il n'y en a qu'un. Alors que dans char* ptr = "abcdef"; il y a bien deux objets, prt et "abcdef".
Qu'on me permette de me défendre (Marc Espie n'est d'ailleurs pas intervenu sur ce point). Voici mon propos initial à ce sujet :
char *str = "abcdefgh";
Il y a deux choses : la chaîne "abcdefgh" (que tu ne peux pas modifier) et le pointeur str (initialisé sur cette chaîne). Alors que dans :
char tab[] = "abcdefgh";
Il n'y a que la chaîne (toujours pas modifiable) *identifiée* par s. Aucun pointeur. Ici, tab n'est pas un pointeur, mais identifie la chaîne.
Cela ne semble pas être en contradiction avec ce que tu viens de dire. J'ai même appuyé cette notion par la suite dans un autre message en des termes quasi identiques aux tiens :
Mon intention était plutôt de faire comprendre à l'OP que la différence entre les 2 expressions était le nombre d'objets créés (2 dans le cas char*, 1 dans le cas char[]).
Ce à quoi Marc Espie a jugé bon de répondre que c'était faux (et, en substance, "qu'est-ce qu'un objet créé ?"). Qui a raison ?
Qu'on me comprenne bien, je ne cherche pas à troller inutilement ici, mais à parfaire ma capacité à expliquer des mécanismes de C (tout en me gardant bien de tenter de saccager le fond de commerce des enseignants :)).
En fait, Marc est intervenu (peut-être à juste titre, c'est ce je cherchais à savoir) sur le fait que je qualifiais un tableau terminé par ' ' de chaîne (à l'exécution). Comme il le dit assez bien, c'est un problème de vocabulaire.
Autre chose : généralement, je préfère éviter le terme de tableau quand je m'adresse à des débutants en C. Je sais bien que ce terme est adéquat dans le cadre de la norme C, mais bien souvent, les débutants en C ont une conception des tableaux autre que celle de la norme C et ils s'y cassent les dents assez vite. D'où mon hésitation à utiliser ce terme, en tous cas, pas sans développer le propos. Ca complique pas mal la nécessité d'être concis pour ne pas l'embrouiller.
Comment evites-tu de parler de tableau ?
Du mieux que je peux, habituellement :) Mais Antoine et Marc m'ont convaincu qu'il est plus difficile d'éviter d'en parler.
-- Alex
On 05/06/2011 10:10 AM, Marc Boyer wrote:
Le 05-05-2011, Alexandre Bacquart<tek512@free.DELETEME.fr> a écrit :
Certes, tout ceci est fort joli (et réel)... il y a tellement de façons
d'optimiser. Mais ce qui m'intéresse plus particulièrement, c'est la
valeur pédagogique de mon propos initial. En quoi mon explication
tendrait à mettre le doute dans la tête l'OP, voire à lui inculquer une
fausse conception (pour ce qu'il a besoin de savoir pour l'instant) ?
Ayant enseigné le C un certain nombre d'années, j'aurais tendance à
dire que ton propos entrainait une confusion, car il supposait que
dans l'écriture
char str[]= "abdcef";
il y a *deux* objets (str, et "abcdef"), alors qu'il n'y en a qu'un.
Alors que dans
char* ptr = "abcdef";
il y a bien deux objets, prt et "abcdef".
Qu'on me permette de me défendre (Marc Espie n'est d'ailleurs pas
intervenu sur ce point). Voici mon propos initial à ce sujet :
char *str = "abcdefgh";
Il y a deux choses : la chaîne "abcdefgh" (que tu ne peux pas modifier) et le pointeur str (initialisé sur cette chaîne). Alors que dans :
char tab[] = "abcdefgh";
Il n'y a que la chaîne (toujours pas modifiable) *identifiée* par s. Aucun pointeur. Ici, tab n'est pas un pointeur, mais identifie la chaîne.
Cela ne semble pas être en contradiction avec ce que tu viens de dire.
J'ai même appuyé cette notion par la suite dans un autre message en des
termes quasi identiques aux tiens :
Mon intention était plutôt de faire comprendre à l'OP que la différence
entre les 2 expressions était le nombre d'objets créés (2 dans le cas
char*, 1 dans le cas char[]).
Ce à quoi Marc Espie a jugé bon de répondre que c'était faux (et, en
substance, "qu'est-ce qu'un objet créé ?"). Qui a raison ?
Qu'on me comprenne bien, je ne cherche pas à troller inutilement ici,
mais à parfaire ma capacité à expliquer des mécanismes de C (tout en me
gardant bien de tenter de saccager le fond de commerce des enseignants :)).
En fait, Marc est intervenu (peut-être à juste titre, c'est ce je
cherchais à savoir) sur le fait que je qualifiais un tableau terminé par
' ' de chaîne (à l'exécution). Comme il le dit assez bien, c'est un
problème de vocabulaire.
Autre chose : généralement, je préfère éviter le terme de tableau quand
je m'adresse à des débutants en C. Je sais bien que ce terme est adéquat
dans le cadre de la norme C, mais bien souvent, les débutants en C ont
une conception des tableaux autre que celle de la norme C et ils s'y
cassent les dents assez vite. D'où mon hésitation à utiliser ce terme,
en tous cas, pas sans développer le propos. Ca complique pas mal la
nécessité d'être concis pour ne pas l'embrouiller.
Comment evites-tu de parler de tableau ?
Du mieux que je peux, habituellement :) Mais Antoine et Marc m'ont
convaincu qu'il est plus difficile d'éviter d'en parler.
Certes, tout ceci est fort joli (et réel)... il y a tellement de façons d'optimiser. Mais ce qui m'intéresse plus particulièrement, c'est la valeur pédagogique de mon propos initial. En quoi mon explication tendrait à mettre le doute dans la tête l'OP, voire à lui inculquer une fausse conception (pour ce qu'il a besoin de savoir pour l'instant) ?
Ayant enseigné le C un certain nombre d'années, j'aurais tendance à dire que ton propos entrainait une confusion, car il supposait que dans l'écriture char str[]= "abdcef"; il y a *deux* objets (str, et "abcdef"), alors qu'il n'y en a qu'un. Alors que dans char* ptr = "abcdef"; il y a bien deux objets, prt et "abcdef".
Qu'on me permette de me défendre (Marc Espie n'est d'ailleurs pas intervenu sur ce point). Voici mon propos initial à ce sujet :
char *str = "abcdefgh";
Il y a deux choses : la chaîne "abcdefgh" (que tu ne peux pas modifier) et le pointeur str (initialisé sur cette chaîne). Alors que dans :
char tab[] = "abcdefgh";
Il n'y a que la chaîne (toujours pas modifiable) *identifiée* par s. Aucun pointeur. Ici, tab n'est pas un pointeur, mais identifie la chaîne.
Cela ne semble pas être en contradiction avec ce que tu viens de dire. J'ai même appuyé cette notion par la suite dans un autre message en des termes quasi identiques aux tiens :
Mon intention était plutôt de faire comprendre à l'OP que la différence entre les 2 expressions était le nombre d'objets créés (2 dans le cas char*, 1 dans le cas char[]).
Ce à quoi Marc Espie a jugé bon de répondre que c'était faux (et, en substance, "qu'est-ce qu'un objet créé ?"). Qui a raison ?
Qu'on me comprenne bien, je ne cherche pas à troller inutilement ici, mais à parfaire ma capacité à expliquer des mécanismes de C (tout en me gardant bien de tenter de saccager le fond de commerce des enseignants :)).
En fait, Marc est intervenu (peut-être à juste titre, c'est ce je cherchais à savoir) sur le fait que je qualifiais un tableau terminé par ' ' de chaîne (à l'exécution). Comme il le dit assez bien, c'est un problème de vocabulaire.
Autre chose : généralement, je préfère éviter le terme de tableau quand je m'adresse à des débutants en C. Je sais bien que ce terme est adéquat dans le cadre de la norme C, mais bien souvent, les débutants en C ont une conception des tableaux autre que celle de la norme C et ils s'y cassent les dents assez vite. D'où mon hésitation à utiliser ce terme, en tous cas, pas sans développer le propos. Ca complique pas mal la nécessité d'être concis pour ne pas l'embrouiller.
Comment evites-tu de parler de tableau ?
Du mieux que je peux, habituellement :) Mais Antoine et Marc m'ont convaincu qu'il est plus difficile d'éviter d'en parler.
-- Alex
espie
In article , -ed- wrote:
Par contre, en POSIX, il existe une fonction strdup(), qui, et il FAUT le savoir, utilise malloc().
Non.
La description de POSIX te dit que le resultat de strdup() peut etre passe a free(). Ce qui n'est pas strictement la meme chose.
Pas du tout bizarrement, strdup() est dans POSIX, mais pas dans ISO C.
C'est totalement intentionnel: strdup() traine dans les systemes depuis avant la normalisation du C... et a ete egalement incorporee en C++. Du coup, sur des vieux systemes, tu ne sais jamais trop si strdup() existe, ni si elle utilise un equivalent de malloc() ou de new en interne. (et de plus, c'est a peu pres la seule fonction associee a string.h qui fait de la gestion memoire).
In article <36a509a3-3619-41fc-8717-cbb2d6115be7@s9g2000yqm.googlegroups.com>,
-ed- <emmanuel.delahaye@gmail.com> wrote:
Par contre, en POSIX, il existe une fonction strdup(), qui, et il FAUT
le savoir, utilise malloc().
Non.
La description de POSIX te dit que le resultat de strdup() peut etre passe
a free(). Ce qui n'est pas strictement la meme chose.
Pas du tout bizarrement, strdup() est dans POSIX, mais pas dans ISO C.
C'est totalement intentionnel: strdup() traine dans les systemes depuis avant
la normalisation du C... et a ete egalement incorporee en C++. Du coup, sur
des vieux systemes, tu ne sais jamais trop si strdup() existe, ni si elle
utilise un equivalent de malloc() ou de new en interne.
(et de plus, c'est a peu pres la seule fonction associee a string.h qui fait
de la gestion memoire).
Par contre, en POSIX, il existe une fonction strdup(), qui, et il FAUT le savoir, utilise malloc().
Non.
La description de POSIX te dit que le resultat de strdup() peut etre passe a free(). Ce qui n'est pas strictement la meme chose.
Pas du tout bizarrement, strdup() est dans POSIX, mais pas dans ISO C.
C'est totalement intentionnel: strdup() traine dans les systemes depuis avant la normalisation du C... et a ete egalement incorporee en C++. Du coup, sur des vieux systemes, tu ne sais jamais trop si strdup() existe, ni si elle utilise un equivalent de malloc() ou de new en interne. (et de plus, c'est a peu pres la seule fonction associee a string.h qui fait de la gestion memoire).
Jean-Marc Bourguet
(Marc Espie) writes:
C'est totalement intentionnel: strdup() traine dans les systemes depuis avant la normalisation du C... et a ete egalement incorporee en C++.
strdup n'est pas plus standardisee en C++ qu'en C.
A+
-- Jean-Marc FAQ de fclc: http://www.levenez.com/lang/c/faq Site de usenet-fr: http://www.usenet-fr.news.eu.org
espie@lain.home (Marc Espie) writes:
C'est totalement intentionnel: strdup() traine dans les systemes depuis avant
la normalisation du C... et a ete egalement incorporee en C++.
strdup n'est pas plus standardisee en C++ qu'en C.
A+
--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Bon c'est pareil. L'un est l'autre se lisent et s'utilisent aussi facilement. Perso j'utilise assez la 1ere écriture (avec *s) quand il s'agit de décrire des pointeurs sur pointeurs de trucs (genres pointeur sur fonction prenant des pointeurs sur int et retournant un tableau de fonctions retournant elles mêmes des pointeurs sur int).
Mais ces cas tordus sont rares, et si on veut être compris de tous il est parfois utile d'ajouter des typedefs pour avoir des combinaisons simples de types plutot qu'une grosse combinaison complexe de type simples.
sam.
Le 07/05/2011 20:17, Pierre Maurette a écrit :
Lucas Levrel, le 5/7/2011 a écrit :
[...]
char *s="coucou";
Ici je lis que *s est un char.
Et pourquoi ce ne serait pas mieux d'écrire:
char* s = "coucou";
Ici je lis que s est un char*.
Bon c'est pareil. L'un est l'autre se lisent et s'utilisent aussi
facilement. Perso j'utilise assez la 1ere écriture (avec *s) quand il
s'agit de décrire des pointeurs sur pointeurs de trucs (genres pointeur
sur fonction prenant des pointeurs sur int et retournant un tableau de
fonctions retournant elles mêmes des pointeurs sur int).
Mais ces cas tordus sont rares, et si on veut être compris de tous il
est parfois utile d'ajouter des typedefs pour avoir des combinaisons
simples de types plutot qu'une grosse combinaison complexe de type simples.
Bon c'est pareil. L'un est l'autre se lisent et s'utilisent aussi facilement. Perso j'utilise assez la 1ere écriture (avec *s) quand il s'agit de décrire des pointeurs sur pointeurs de trucs (genres pointeur sur fonction prenant des pointeurs sur int et retournant un tableau de fonctions retournant elles mêmes des pointeurs sur int).
Mais ces cas tordus sont rares, et si on veut être compris de tous il est parfois utile d'ajouter des typedefs pour avoir des combinaisons simples de types plutot qu'une grosse combinaison complexe de type simples.
sam.
Xavier Roche
Le 07/05/2011 20:17, Pierre Maurette a écrit :
Et pourquoi ce ne serait pas mieux d'écrire: char* s = "coucou";
Quand à chipoter, ce qui manque surtout, c'est le "const": const char* s = "coucou";
Le 07/05/2011 20:17, Pierre Maurette a écrit :
Et pourquoi ce ne serait pas mieux d'écrire:
char* s = "coucou";
Quand à chipoter, ce qui manque surtout, c'est le "const":
const char* s = "coucou";
Et pourquoi ce ne serait pas mieux d'écrire: char* s = "coucou";
Quand à chipoter, ce qui manque surtout, c'est le "const": const char* s = "coucou";
Pierre Maurette
Xavier Roche, le 5/7/2011 a écrit :
Le 07/05/2011 20:17, Pierre Maurette a écrit :
Et pourquoi ce ne serait pas mieux d'écrire: char* s = "coucou";
Quand à chipoter, ce qui manque surtout, c'est le "const": const char* s = "coucou";
Oui. J'ai perdu du temps avec ce bordel. s est un /char étoile/ non modifiable. En fait un pointeur sur une chaîne en dur. Un littéral chaîne. Le littéral chaîne n'existe que pendant les instants de la compilation.
-- Pierre Maurette
Xavier Roche, le 5/7/2011 a écrit :
Le 07/05/2011 20:17, Pierre Maurette a écrit :
Et pourquoi ce ne serait pas mieux d'écrire:
char* s = "coucou";
Quand à chipoter, ce qui manque surtout, c'est le "const":
const char* s = "coucou";
Oui. J'ai perdu du temps avec ce bordel. s est un /char étoile/ non
modifiable. En fait un pointeur sur une chaîne en dur. Un littéral
chaîne.
Le littéral chaîne n'existe que pendant les instants de la compilation.
Et pourquoi ce ne serait pas mieux d'écrire: char* s = "coucou";
Quand à chipoter, ce qui manque surtout, c'est le "const": const char* s = "coucou";
Oui. J'ai perdu du temps avec ce bordel. s est un /char étoile/ non modifiable. En fait un pointeur sur une chaîne en dur. Un littéral chaîne. Le littéral chaîne n'existe que pendant les instants de la compilation.