Je d=E9bute avec le C depuis quelques mois =E0 mon rhytme. J'arrive au
chapitre de l'allocation dynamique. J'ai abord=E9 les tableaux uni et
multidimensionnels, les pointeurs, les fonctions.
En fait, je comprends l'utilit=E9 de malloc dans le sens ou la
r=E9servation de la m=E9moire pour un tableau peut se faire en cours
d'ex=E9cution...
Pour la saisie de texte, je voudrais savoir s'il serait possible de
saisir une cha=EEne de caract=E8re variable avec fgets ? Je pense beaucoup
=E0 utiliser realloc.
Par exemple : je r=E9serve de la m=E9moire pour un pointeur vers une
adresse de type caract=E8re, pour 1 ou 2 caract=E8res et =E0 je demande =E0
l'utilisateur de saisir du texte. A chaque saisie, je r=E9serve la place
pour un caract=E8re suppl=E9mentaire en m=E9moire avec realloc, c'est
faisable? Bizarement, je ne trouve aucun code qui correspond =E0 ce que
je recherche sur le net.
Ca ressemble =E0 peu pr=E8s, mais =E7a ne marche pas :
http://www.cppfrance.com/forum/sujet-RECUERATION-CHAINE-CARACTERE-TAILLE-VA=
RIABLE-STDIN_1405662.aspx
Autre question sans lien avec la premi=E8re :
est-ce que =E9crire char* chaine =3D 0 et char *chaine =3D 0 revient =E0 la
m=EAme chose?
[realloc: capacite+=constante vs capacite*=constante]
On prefere le 2e schema dans l'enorme majorite des applications. Sur la plupart des OS, le plus souvent, il n'y a "pas de place" apres ton tableau, et realloc revient donc a allouer un nouveau tableau et tout copier...
Tu es peut-être un peu pessimiste. Si on fait un malloc(1) suivi de p=realloc(p,i++) en boucle et qu'on vérifie à quelles étapes realloc renvoie un pointeur différent, avec beaucoup d'allocateurs, on constate une progression géométrique collant précisément à ce capacite*=constante. Ce qui ne veut pas dire qu'il faut compter sur ce comportement, il vaut effectivement mieux gérer soi-même le doublement de capacité en supposant que realloc n'est pas plus efficace que malloc+memcpy+free.
Attention là tu viens de foutre en l'air ton traitement d'erreur...
si ton realloc te renvoie NULL, tu as en plus une belle fuite mémoire car tu as perdu l'ancien pointeur, mais la zone n'a pas été désallouée. C'est un des dangers de realloc...
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
Marc <marc.glisse@gmail.com> écrivait :
Marc Espie wrote:
[realloc: capacite+=constante vs capacite*=constante]
On prefere le 2e schema dans l'enorme majorite des applications. Sur la
plupart des OS, le plus souvent, il n'y a "pas de place" apres ton tableau,
et realloc revient donc a allouer un nouveau tableau et tout copier...
Tu es peut-être un peu pessimiste. Si on fait un malloc(1) suivi de
p=realloc(p,i++) en boucle et qu'on vérifie à quelles étapes realloc
renvoie un pointeur différent, avec beaucoup d'allocateurs, on constate
une progression géométrique collant précisément à ce capacite*=constante.
Ce qui ne veut pas dire qu'il faut compter sur ce comportement, il vaut
effectivement mieux gérer soi-même le doublement de capacité en supposant
que realloc n'est pas plus efficace que malloc+memcpy+free.
Attention là tu viens de foutre en l'air ton traitement d'erreur...
si ton realloc te renvoie NULL, tu as en plus une belle fuite mémoire
car tu as perdu l'ancien pointeur, mais la zone n'a pas été désallouée.
C'est un des dangers de realloc...
--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
[realloc: capacite+=constante vs capacite*=constante]
On prefere le 2e schema dans l'enorme majorite des applications. Sur la plupart des OS, le plus souvent, il n'y a "pas de place" apres ton tableau, et realloc revient donc a allouer un nouveau tableau et tout copier...
Tu es peut-être un peu pessimiste. Si on fait un malloc(1) suivi de p=realloc(p,i++) en boucle et qu'on vérifie à quelles étapes realloc renvoie un pointeur différent, avec beaucoup d'allocateurs, on constate une progression géométrique collant précisément à ce capacite*=constante. Ce qui ne veut pas dire qu'il faut compter sur ce comportement, il vaut effectivement mieux gérer soi-même le doublement de capacité en supposant que realloc n'est pas plus efficace que malloc+memcpy+free.
Attention là tu viens de foutre en l'air ton traitement d'erreur...
si ton realloc te renvoie NULL, tu as en plus une belle fuite mémoire car tu as perdu l'ancien pointeur, mais la zone n'a pas été désallouée. C'est un des dangers de realloc...
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
espie
In article <hsn5ko$ica$, Marc wrote:
Marc Espie wrote:
[realloc: capacite+=constante vs capacite*=constante]
On prefere le 2e schema dans l'enorme majorite des applications. Sur la plupart des OS, le plus souvent, il n'y a "pas de place" apres ton tableau, et realloc revient donc a allouer un nouveau tableau et tout copier...
Tu es peut-être un peu pessimiste. Si on fait un malloc(1) suivi de p=realloc(p,i++) en boucle et qu'on vérifie à quelles étapes realloc renvoie un pointeur différent, avec beaucoup d'allocateurs, on constate une progression géométrique collant précisément à ce capacite*=constante. Ce qui ne veut pas dire qu'il faut compter sur ce comportement, il vaut effectivement mieux gérer soi-même le doublement de capacité en supposant que realloc n'est pas plus efficace que malloc+memcpy+free.
Ah oui, tiens, c'est une consequence logique du fonctionnement des allocateurs modernes. Par contre, dans l'enorme majorite des cas, ce comportement va s'arreter au-dela d'une certaine taille (les allocateurs "par puissance de 2" ont generalement un seuil au-dessus duquel ils font directement appel a mmap)
In article <hsn5ko$ica$1@nef.ens.fr>, Marc <marc.glisse@gmail.com> wrote:
Marc Espie wrote:
[realloc: capacite+=constante vs capacite*=constante]
On prefere le 2e schema dans l'enorme majorite des applications. Sur la
plupart des OS, le plus souvent, il n'y a "pas de place" apres ton tableau,
et realloc revient donc a allouer un nouveau tableau et tout copier...
Tu es peut-être un peu pessimiste. Si on fait un malloc(1) suivi de
p=realloc(p,i++) en boucle et qu'on vérifie à quelles étapes realloc
renvoie un pointeur différent, avec beaucoup d'allocateurs, on constate
une progression géométrique collant précisément à ce capacite*=constante.
Ce qui ne veut pas dire qu'il faut compter sur ce comportement, il vaut
effectivement mieux gérer soi-même le doublement de capacité en supposant
que realloc n'est pas plus efficace que malloc+memcpy+free.
Ah oui, tiens, c'est une consequence logique du fonctionnement des allocateurs
modernes. Par contre, dans l'enorme majorite des cas, ce comportement va
s'arreter au-dela d'une certaine taille (les allocateurs "par puissance de 2"
ont generalement un seuil au-dessus duquel ils font directement appel a mmap)
[realloc: capacite+=constante vs capacite*=constante]
On prefere le 2e schema dans l'enorme majorite des applications. Sur la plupart des OS, le plus souvent, il n'y a "pas de place" apres ton tableau, et realloc revient donc a allouer un nouveau tableau et tout copier...
Tu es peut-être un peu pessimiste. Si on fait un malloc(1) suivi de p=realloc(p,i++) en boucle et qu'on vérifie à quelles étapes realloc renvoie un pointeur différent, avec beaucoup d'allocateurs, on constate une progression géométrique collant précisément à ce capacite*=constante. Ce qui ne veut pas dire qu'il faut compter sur ce comportement, il vaut effectivement mieux gérer soi-même le doublement de capacité en supposant que realloc n'est pas plus efficace que malloc+memcpy+free.
Ah oui, tiens, c'est une consequence logique du fonctionnement des allocateurs modernes. Par contre, dans l'enorme majorite des cas, ce comportement va s'arreter au-dela d'une certaine taille (les allocateurs "par puissance de 2" ont generalement un seuil au-dessus duquel ils font directement appel a mmap)
Xavier Roche
Marc Espie a écrit :
Tu es peut-être un peu pessimiste. Si on fait un malloc(1) suivi de p=realloc(p,i++) en boucle et qu'on vérifie à quelles étapes realloc renvoie un pointeur différent, avec beaucoup d'allocateurs, on constate une progression géométrique collant précisément à ce capacite*=constante.
Ce n'est pas vrai sous Windows, de mémoire, avec la libc Microsoft. Cela peut entrainer des bugs de perfs assez gigantesques, si on compte sur l'effet géométrique de l'allocateur, car celui-ci n'existe pas toujours.
Marc Espie a écrit :
Tu es peut-être un peu pessimiste. Si on fait un malloc(1) suivi de
p=realloc(p,i++) en boucle et qu'on vérifie à quelles étapes realloc
renvoie un pointeur différent, avec beaucoup d'allocateurs, on constate
une progression géométrique collant précisément à ce capacite*=constante.
Ce n'est pas vrai sous Windows, de mémoire, avec la libc Microsoft. Cela
peut entrainer des bugs de perfs assez gigantesques, si on compte sur
l'effet géométrique de l'allocateur, car celui-ci n'existe pas toujours.
Tu es peut-être un peu pessimiste. Si on fait un malloc(1) suivi de p=realloc(p,i++) en boucle et qu'on vérifie à quelles étapes realloc renvoie un pointeur différent, avec beaucoup d'allocateurs, on constate une progression géométrique collant précisément à ce capacite*=constante.
Ce n'est pas vrai sous Windows, de mémoire, avec la libc Microsoft. Cela peut entrainer des bugs de perfs assez gigantesques, si on compte sur l'effet géométrique de l'allocateur, car celui-ci n'existe pas toujours.
Je vais faire mon persifleur, alors... la derniere fois que j'ai vu un allocateur sans puissances de 2 sous un unixoide, ca devait etre il y a une bonne dizaine d'annees. Tout le monde savait deja que c'etait mauvais en termes de perfs pour la plupart des appli (et qu'une appli jouant avec sa memoire de facon intensive allait tres vite bouffer toute la memoire disponible pour elle sur le systeme, donc soit faire ramer tout le monde, soit se faire tuer par depassement de son rusage).
Si microsoft n'a toujours pas compris ca (enfin, je pense qu'ils ont compris, mais doit encore y avoir une histoire de sacro-sainte compatibilite binaire a la noix), ca expliquerait en grande partie pourquoi ce systeme est monstrueusement gourmand en occupation memoire: les allocateurs sous-optimaux, ca a une nette tendance a fractionner la memoire a la vitesse grand V.
Bien joue les mecs...
In article <hsog6f$e9f$1@news.httrack.net>,
Xavier Roche <xroche@free.fr.NOSPAM.invalid> wrote:
Je vais faire mon persifleur, alors... la derniere fois que j'ai vu un
allocateur sans puissances de 2 sous un unixoide, ca devait etre il y a une
bonne dizaine d'annees. Tout le monde savait deja que c'etait mauvais en
termes de perfs pour la plupart des appli (et qu'une appli jouant avec
sa memoire de facon intensive allait tres vite bouffer toute la memoire
disponible pour elle sur le systeme, donc soit faire ramer tout le monde,
soit se faire tuer par depassement de son rusage).
Si microsoft n'a toujours pas compris ca (enfin, je pense qu'ils ont compris,
mais doit encore y avoir une histoire de sacro-sainte compatibilite binaire
a la noix), ca expliquerait en grande partie pourquoi ce systeme est
monstrueusement gourmand en occupation memoire: les allocateurs sous-optimaux,
ca a une nette tendance a fractionner la memoire a la vitesse grand V.
Je vais faire mon persifleur, alors... la derniere fois que j'ai vu un allocateur sans puissances de 2 sous un unixoide, ca devait etre il y a une bonne dizaine d'annees. Tout le monde savait deja que c'etait mauvais en termes de perfs pour la plupart des appli (et qu'une appli jouant avec sa memoire de facon intensive allait tres vite bouffer toute la memoire disponible pour elle sur le systeme, donc soit faire ramer tout le monde, soit se faire tuer par depassement de son rusage).
Si microsoft n'a toujours pas compris ca (enfin, je pense qu'ils ont compris, mais doit encore y avoir une histoire de sacro-sainte compatibilite binaire a la noix), ca expliquerait en grande partie pourquoi ce systeme est monstrueusement gourmand en occupation memoire: les allocateurs sous-optimaux, ca a une nette tendance a fractionner la memoire a la vitesse grand V.
Bien joue les mecs...
Antoine Leca
heron écrivit :
Fgets place les données sur le "tas" (heap).
Non. fgets() place les données reçues dans le tableau passé en argument (ainsi que sa taille réelle). Et c'est la responsabilité du programmeur que d'avoir alloué ce tableau auparavant, que ce soit avec une allocation statique (sur la pile)
char Txt[5] ;
ou dynamique (sur le tas) Txt = ÞÞÞÞalloc()
("ÞÞÞÞ" pouvant être "m", "c", "re").
La logique de C est de séparer le plus nettement possible d'un côté les algorithmes qui utilisent les objets, et de l'autre la gestion de mémoire, dont l'allocation des dits objets. fgets() et les fonctions en général s'occupent du premier côté ; malloc(), calloc(), realloc(), free(), plus les mots clés static et auto et plus généralement la syntaxe des déclarations d'objets, sont quasiment les seuls qui s'occupent de la gestion de la mémoire.
Antoine
heron écrivit :
Fgets place les données sur le "tas" (heap).
Non. fgets() place les données reçues dans le tableau passé en argument
(ainsi que sa taille réelle).
Et c'est la responsabilité du programmeur que d'avoir alloué ce tableau
auparavant, que ce soit avec une allocation statique (sur la pile)
char Txt[5] ;
ou dynamique (sur le tas)
Txt = ÞÞÞÞalloc()
("ÞÞÞÞ" pouvant être "m", "c", "re").
La logique de C est de séparer le plus nettement possible d'un côté les
algorithmes qui utilisent les objets, et de l'autre la gestion de
mémoire, dont l'allocation des dits objets.
fgets() et les fonctions en général s'occupent du premier côté ;
malloc(), calloc(), realloc(), free(), plus les mots clés static et auto
et plus généralement la syntaxe des déclarations d'objets, sont
quasiment les seuls qui s'occupent de la gestion de la mémoire.
Non. fgets() place les données reçues dans le tableau passé en argument (ainsi que sa taille réelle). Et c'est la responsabilité du programmeur que d'avoir alloué ce tableau auparavant, que ce soit avec une allocation statique (sur la pile)
char Txt[5] ;
ou dynamique (sur le tas) Txt = ÞÞÞÞalloc()
("ÞÞÞÞ" pouvant être "m", "c", "re").
La logique de C est de séparer le plus nettement possible d'un côté les algorithmes qui utilisent les objets, et de l'autre la gestion de mémoire, dont l'allocation des dits objets. fgets() et les fonctions en général s'occupent du premier côté ; malloc(), calloc(), realloc(), free(), plus les mots clés static et auto et plus généralement la syntaxe des déclarations d'objets, sont quasiment les seuls qui s'occupent de la gestion de la mémoire.
Antoine
heron
On May 17, 8:48 am, Antoine Leca wrote:
heron écrivit :
> Fgets place les données sur le "tas" (heap).
Non. fgets() place les données reçues dans le tableau passé en argu ment (ainsi que sa taille réelle). Et c'est la responsabilité du programmeur que d'avoir alloué ce table au auparavant, que ce soit avec une allocation statique (sur la pile)> char Txt[5] ;
ou dynamique (sur le tas) Txt = ÞÞÞÞalloc()
("ÞÞÞÞ" pouvant être "m", "c", "re").
La logique de C est de séparer le plus nettement possible d'un côté les algorithmes qui utilisent les objets, et de l'autre la gestion de mémoire, dont l'allocation des dits objets. fgets() et les fonctions en général s'occupent du premier côté ; malloc(), calloc(), realloc(), free(), plus les mots clés static et aut o et plus généralement la syntaxe des déclarations d'objets, sont quasiment les seuls qui s'occupent de la gestion de la mémoire.
Antoine
très clair, merci (j'en redemande)
On May 17, 8:48 am, Antoine Leca <r...@localhost.invalid> wrote:
heron écrivit :
> Fgets place les données sur le "tas" (heap).
Non. fgets() place les données reçues dans le tableau passé en argu ment
(ainsi que sa taille réelle).
Et c'est la responsabilité du programmeur que d'avoir alloué ce table au
auparavant, que ce soit avec une allocation statique (sur la pile)> char Txt[5] ;
ou dynamique (sur le tas)
Txt = ÞÞÞÞalloc()
("ÞÞÞÞ" pouvant être "m", "c", "re").
La logique de C est de séparer le plus nettement possible d'un côté les
algorithmes qui utilisent les objets, et de l'autre la gestion de
mémoire, dont l'allocation des dits objets.
fgets() et les fonctions en général s'occupent du premier côté ;
malloc(), calloc(), realloc(), free(), plus les mots clés static et aut o
et plus généralement la syntaxe des déclarations d'objets, sont
quasiment les seuls qui s'occupent de la gestion de la mémoire.
Non. fgets() place les données reçues dans le tableau passé en argu ment (ainsi que sa taille réelle). Et c'est la responsabilité du programmeur que d'avoir alloué ce table au auparavant, que ce soit avec une allocation statique (sur la pile)> char Txt[5] ;
ou dynamique (sur le tas) Txt = ÞÞÞÞalloc()
("ÞÞÞÞ" pouvant être "m", "c", "re").
La logique de C est de séparer le plus nettement possible d'un côté les algorithmes qui utilisent les objets, et de l'autre la gestion de mémoire, dont l'allocation des dits objets. fgets() et les fonctions en général s'occupent du premier côté ; malloc(), calloc(), realloc(), free(), plus les mots clés static et aut o et plus généralement la syntaxe des déclarations d'objets, sont quasiment les seuls qui s'occupent de la gestion de la mémoire.
Antoine
très clair, merci (j'en redemande)
heron
Je ne vois pas la différence entre : ... cnt = 0 ; cnt++ ; numbers = (int *) realloc(numbers, cnt * sizeof(int) ) ; ... et ... i = 0 ; ++i ; chaine = realloc(chaine, (i+1) * sizeof(char) ) ;
Dans le premier cas, lors de la première reallocation, cnt = 1 alors 1 * 2 = 2 ou 1 * 4 = 4 soit la place pour un et un seul entier suivant. Dans le second cas, au premier appel, i = 2 alors 2 * 1 = 2 soit la place pour 2 autres caractères.
Est-ce que ce qui différencie la variable cnt et la variable int est le type de données qu'elles se chargent de réserver? Pour un nombre entier, il s'agirait alors juste d'un nombre entier supplémantaire alors que pour la variable caractère il y aurait également le caractère de fin de tableaux de caractère ' ' ?
Plus haut dans cette discussion, il est question de savoir si c'est mieux d'additionner que de multiplier mais je ne suis pas encore à ce niveau pour me poser ce genre de question. Je voudrais juste être sûre de comprendre les bases.
Je ne vois pas la différence entre :
...
cnt = 0 ;
cnt++ ;
numbers = (int *) realloc(numbers, cnt * sizeof(int) ) ;
...
et
...
i = 0 ;
++i ;
chaine = realloc(chaine, (i+1) * sizeof(char) ) ;
Dans le premier cas, lors de la première reallocation, cnt = 1 alors 1
* 2 = 2 ou 1 * 4 = 4 soit la place pour un et un seul entier suivant.
Dans le second cas, au premier appel, i = 2 alors 2 * 1 = 2 soit la
place pour 2 autres caractères.
Est-ce que ce qui différencie la variable cnt et la variable int est
le type de données qu'elles se chargent de réserver? Pour un nombre
entier, il s'agirait alors juste d'un nombre entier supplémantaire
alors que pour la variable caractère il y aurait également le
caractère de fin de tableaux de caractère ' ' ?
Plus haut dans cette discussion, il est question de savoir si c'est
mieux d'additionner que de multiplier mais je ne suis pas encore à ce
niveau pour me poser ce genre de question. Je voudrais juste être sûre
de comprendre les bases.
Je ne vois pas la différence entre : ... cnt = 0 ; cnt++ ; numbers = (int *) realloc(numbers, cnt * sizeof(int) ) ; ... et ... i = 0 ; ++i ; chaine = realloc(chaine, (i+1) * sizeof(char) ) ;
Dans le premier cas, lors de la première reallocation, cnt = 1 alors 1 * 2 = 2 ou 1 * 4 = 4 soit la place pour un et un seul entier suivant. Dans le second cas, au premier appel, i = 2 alors 2 * 1 = 2 soit la place pour 2 autres caractères.
Est-ce que ce qui différencie la variable cnt et la variable int est le type de données qu'elles se chargent de réserver? Pour un nombre entier, il s'agirait alors juste d'un nombre entier supplémantaire alors que pour la variable caractère il y aurait également le caractère de fin de tableaux de caractère ' ' ?
Plus haut dans cette discussion, il est question de savoir si c'est mieux d'additionner que de multiplier mais je ne suis pas encore à ce niveau pour me poser ce genre de question. Je voudrais juste être sûre de comprendre les bases.
Samuel DEVULDER
heron a écrit :
Je ne vois pas la différence entre : ... cnt = 0 ; cnt++ ; numbers = (int *) realloc(numbers, cnt * sizeof(int) ) ; ... et ... i = 0 ; ++i ; chaine = realloc(chaine, (i+1) * sizeof(char) ) ;
Normal! il n'y en a pas.. C'est bonnet-blanc ou blanc-bonnet, au choix. Il y a juste un "+1" sur i peut-être pour l'histoire du final, mais ca ne change rien.
sam.
heron a écrit :
Je ne vois pas la différence entre :
...
cnt = 0 ;
cnt++ ;
numbers = (int *) realloc(numbers, cnt * sizeof(int) ) ;
...
et
...
i = 0 ;
++i ;
chaine = realloc(chaine, (i+1) * sizeof(char) ) ;
Normal! il n'y en a pas.. C'est bonnet-blanc ou blanc-bonnet, au choix.
Il y a juste un "+1" sur i peut-être pour l'histoire du final, mais
ca ne change rien.
Je ne vois pas la différence entre : ... cnt = 0 ; cnt++ ; numbers = (int *) realloc(numbers, cnt * sizeof(int) ) ; ... et ... i = 0 ; ++i ; chaine = realloc(chaine, (i+1) * sizeof(char) ) ;
Normal! il n'y en a pas.. C'est bonnet-blanc ou blanc-bonnet, au choix. Il y a juste un "+1" sur i peut-être pour l'histoire du final, mais ca ne change rien.
sam.
Antoine Leca
heron écrivit :
Je ne vois pas la différence entre : ... cnt = 0 ; cnt++ ; numbers = (int *) realloc(numbers, cnt * sizeof(int) ) ; ... et ... i = 0 ; ++i ; chaine = realloc(chaine, (i+1) * sizeof(char) ) ;
Dans le premier cas, lors de la première reallocation, cnt = 1 alors 1 * 2 = 2 ou 1 * 4 = 4 soit la place pour un et un seul entier suivant.
Attention, cela fait _ou défait_ la place pour un seul entier _tout court_ ; donc si avant le realloc() numbers était un pointeur vers l'espace pour dix entiers, après le realloc tu as _perdu_ les neuf derniers, d'accord ?
Dans le second cas, au premier appel, i = 2 alors 2 * 1 = 2 soit la place pour 2 autres caractères.
Idem, pas deux _autres_ mais deux _en tout_.
Antoine
heron écrivit :
Je ne vois pas la différence entre :
...
cnt = 0 ;
cnt++ ;
numbers = (int *) realloc(numbers, cnt * sizeof(int) ) ;
...
et
...
i = 0 ;
++i ;
chaine = realloc(chaine, (i+1) * sizeof(char) ) ;
Dans le premier cas, lors de la première reallocation, cnt = 1 alors 1
* 2 = 2 ou 1 * 4 = 4 soit la place pour un et un seul entier suivant.
Attention, cela fait _ou défait_ la place pour un seul entier _tout
court_ ; donc si avant le realloc() numbers était un pointeur vers
l'espace pour dix entiers, après le realloc tu as _perdu_ les neuf
derniers, d'accord ?
Dans le second cas, au premier appel, i = 2 alors 2 * 1 = 2 soit la
place pour 2 autres caractères.
Je ne vois pas la différence entre : ... cnt = 0 ; cnt++ ; numbers = (int *) realloc(numbers, cnt * sizeof(int) ) ; ... et ... i = 0 ; ++i ; chaine = realloc(chaine, (i+1) * sizeof(char) ) ;
Dans le premier cas, lors de la première reallocation, cnt = 1 alors 1 * 2 = 2 ou 1 * 4 = 4 soit la place pour un et un seul entier suivant.
Attention, cela fait _ou défait_ la place pour un seul entier _tout court_ ; donc si avant le realloc() numbers était un pointeur vers l'espace pour dix entiers, après le realloc tu as _perdu_ les neuf derniers, d'accord ?
Dans le second cas, au premier appel, i = 2 alors 2 * 1 = 2 soit la place pour 2 autres caractères.
Idem, pas deux _autres_ mais deux _en tout_.
Antoine
Samuel DEVULDER
Antoine Leca a écrit :
Attention, cela fait _ou défait_ la place pour un seul entier _tout court_ ; donc si avant le realloc() numbers était un pointeur vers l'espace pour dix entiers, après le realloc tu as _perdu_ les neuf derniers, d'accord ?
../..
Idem, pas deux _autres_ mais deux _en tout_.
Arf.. Tres bonne remarque, j'avais même pas vu que Heron pouvait penser que realloc travaillait en relatif "augmentait" ou "diminuais" la zone mémoire du pointeur. Ca ne m'etait jammais venu à l'esprit que quelqu'un imagine cela (le manpage est clair au sujet de realloc).
Heron: la taille passée à realloc() est une taille absolue (comme malloc), pas relative! C'est super important à comprendre!
sam (Tapons ou Héron? Héron petit, pas Tapons :) )
Antoine Leca a écrit :
Attention, cela fait _ou défait_ la place pour un seul entier _tout
court_ ; donc si avant le realloc() numbers était un pointeur vers
l'espace pour dix entiers, après le realloc tu as _perdu_ les neuf
derniers, d'accord ?
../..
Idem, pas deux _autres_ mais deux _en tout_.
Arf.. Tres bonne remarque, j'avais même pas vu que Heron pouvait penser
que realloc travaillait en relatif "augmentait" ou "diminuais" la zone
mémoire du pointeur. Ca ne m'etait jammais venu à l'esprit que quelqu'un
imagine cela (le manpage est clair au sujet de realloc).
Heron: la taille passée à realloc() est une taille absolue (comme
malloc), pas relative! C'est super important à comprendre!
sam (Tapons ou Héron? Héron petit, pas Tapons :) )
Attention, cela fait _ou défait_ la place pour un seul entier _tout court_ ; donc si avant le realloc() numbers était un pointeur vers l'espace pour dix entiers, après le realloc tu as _perdu_ les neuf derniers, d'accord ?
../..
Idem, pas deux _autres_ mais deux _en tout_.
Arf.. Tres bonne remarque, j'avais même pas vu que Heron pouvait penser que realloc travaillait en relatif "augmentait" ou "diminuais" la zone mémoire du pointeur. Ca ne m'etait jammais venu à l'esprit que quelqu'un imagine cela (le manpage est clair au sujet de realloc).
Heron: la taille passée à realloc() est une taille absolue (comme malloc), pas relative! C'est super important à comprendre!
sam (Tapons ou Héron? Héron petit, pas Tapons :) )