Non, un free ne peut prendre que le pointeur original. L'allocateur ne
peut pas libérer le bloc si il n'a pas cette adresse.
Ou alors, est-ce que copier le buffer dans le même buffer fonctionnerait ?
Non. Utiliser memmove()
"memmove - copy bytes in memory with overlapping areas"
http://pubs.opengroup.org/onlinepubs/007904875/functions/memmove.html
[memcpy] "If copying takes place between objects that overlap, the
behavior is undefined."
http://pubs.opengroup.org/onlinepubs/009604599/functions/memcpy.html
Non, un free ne peut prendre que le pointeur original. L'allocateur ne
peut pas libérer le bloc si il n'a pas cette adresse.
Ou alors, est-ce que copier le buffer dans le même buffer
fonctionnerait ?
Non. Utiliser memmove()
"memmove - copy bytes in memory with overlapping areas"
http://pubs.opengroup.org/onlinepubs/007904875/functions/memmove.html
[memcpy] "If copying takes place between objects that overlap, the
behavior is undefined."
http://pubs.opengroup.org/onlinepubs/009604599/functions/memcpy.html
Pardon, je voulais parler évidemment de memmove. Merci.
Le Mon, 21 Nov 2011 22:32:11 +0100, TSalm <tsalm@free.fr> a écrit:
free( buff );
Non, un free ne peut prendre que le pointeur original. L'allocateur ne
peut pas libérer le bloc si il n'a pas cette adresse.
Ou alors, est-ce que copier le buffer dans le même buffer
fonctionnerait ?
Non. Utiliser memmove()
"memmove - copy bytes in memory with overlapping areas"
http://pubs.opengroup.org/onlinepubs/007904875/functions/memmove.html
[memcpy] "If copying takes place between objects that overlap, the
behavior is undefined."
http://pubs.opengroup.org/onlinepubs/009604599/functions/memcpy.html
Je ne connaissais pas memcpy. Merci!
Pardon, je voulais parler évidemment de memmove.
Merci.
Pardon, je voulais parler évidemment de memmove. Merci.
JKB
Le Mon, 21 Nov 2011 22:28:26 +0100, Xavier Roche écrivait :
Le 21/11/2011 22:22, TSalm a écrit :
free( buff );
Non, un free ne peut prendre que le pointeur original. L'allocateur ne peut pas libérer le bloc si il n'a pas cette adresse.
J'ajouterais que c'est parce que la plupart des allocateurs utilisent la mémoire avant le pointeur retourné par malloc() pour stocker tout un tas de choses dont la longueur de la zone allouée.
Le Mon, 21 Nov 2011 22:28:26 +0100,
Xavier Roche <xroche@free.fr.NOSPAM.invalid> écrivait :
Le 21/11/2011 22:22, TSalm a écrit :
free( buff );
Non, un free ne peut prendre que le pointeur original. L'allocateur ne
peut pas libérer le bloc si il n'a pas cette adresse.
J'ajouterais que c'est parce que la plupart des allocateurs
utilisent la mémoire avant le pointeur retourné par malloc() pour
stocker tout un tas de choses dont la longueur de la zone allouée.
JKB
--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Le Mon, 21 Nov 2011 22:28:26 +0100, Xavier Roche écrivait :
Le 21/11/2011 22:22, TSalm a écrit :
free( buff );
Non, un free ne peut prendre que le pointeur original. L'allocateur ne peut pas libérer le bloc si il n'a pas cette adresse.
J'ajouterais que c'est parce que la plupart des allocateurs utilisent la mémoire avant le pointeur retourné par malloc() pour stocker tout un tas de choses dont la longueur de la zone allouée.
Je souhaiterais déplacer une chaîne de char. Si je faisais quelquechose comme ça, est-ce que la mémoire serait correctement liberée ? ______________________________________________ char* buff = malloc(sizeof(char)*200); [...valorise buff...] buff = buff + sizeof(char) * 50; printf( buff ); free( buff ); ______________________________________________
Ben non: la valeur de buff envoyée au free() ne correspond pas à celle retournée par un malloc(). Pourquoi ne passes tu pas buff+50 directement au printf? Si tu préfères déclares un bloc après le malloc et un pointeur représentant buff+50:
Nota: pour la simplicité on ne se préoccupe volontairement pas de savoir si 50 signifie quelque chose (offsetof?) ou du fait que le printf() n'utilise pas de chaine de format ce qui est mauvais si le buff contient un %s ou un %d... Ici seul compte qu'il faut faire free() de la valeur retournée par un malloc() (et pas valeur+50).
Ou alors, est-ce que copier le buffer dans le même buffer fonctionnerait ?
DESCRIPTION (...) *If the regions overlap, the behavior is undefined.*
$ man memmove MEMMOVE(3) NEWLIB MEMMOVE(3)
NAME 6.10 `memmove'--move *possibly overlapping* memory
sam.
Le 21/11/2011 22:22, TSalm a écrit :
Bonjour,
Je souhaiterais déplacer une chaîne de char.
Si je faisais quelquechose comme ça, est-ce que la mémoire serait
correctement liberée ?
______________________________________________
char* buff = malloc(sizeof(char)*200);
[...valorise buff...]
buff = buff + sizeof(char) * 50;
printf( buff );
free( buff );
______________________________________________
Ben non: la valeur de buff envoyée au free() ne correspond pas à celle
retournée par un malloc(). Pourquoi ne passes tu pas buff+50
directement au printf? Si tu préfères déclares un bloc après le malloc
et un pointeur représentant buff+50:
Nota: pour la simplicité on ne se préoccupe volontairement pas de
savoir si 50 signifie quelque chose (offsetof?) ou du fait que le
printf() n'utilise pas de chaine de format ce qui est mauvais si le
buff contient un %s ou un %d... Ici seul compte qu'il faut faire free()
de la valeur retournée par un malloc() (et pas valeur+50).
Ou alors, est-ce que copier le buffer dans le même buffer fonctionnerait ?
Je souhaiterais déplacer une chaîne de char. Si je faisais quelquechose comme ça, est-ce que la mémoire serait correctement liberée ? ______________________________________________ char* buff = malloc(sizeof(char)*200); [...valorise buff...] buff = buff + sizeof(char) * 50; printf( buff ); free( buff ); ______________________________________________
Ben non: la valeur de buff envoyée au free() ne correspond pas à celle retournée par un malloc(). Pourquoi ne passes tu pas buff+50 directement au printf? Si tu préfères déclares un bloc après le malloc et un pointeur représentant buff+50:
Nota: pour la simplicité on ne se préoccupe volontairement pas de savoir si 50 signifie quelque chose (offsetof?) ou du fait que le printf() n'utilise pas de chaine de format ce qui est mauvais si le buff contient un %s ou un %d... Ici seul compte qu'il faut faire free() de la valeur retournée par un malloc() (et pas valeur+50).
Ou alors, est-ce que copier le buffer dans le même buffer fonctionnerait ?
Pas mal d'allocateurs modernes sont dits "a puissance de 2", et vont betement agreger les allocations de taille similaire dans une meme page memoire (et retrouver les infos de taille directement a partir de l'adresse).
Le gros avantage par rapport aux trucs antiques, c'est qu'il y a beaucoup moins d'overhead pour les petites allocations...
Par contre, ceux-ci vont raler des qu'on leur passe une adresse qui ne colle pas avec ce qu'ils s'attendent a avoir. Typiquement, si j'ai alloue 128 octets, et que je passe une adresse a +64, l'allocateur va determiner la page, trouver que celle-ci est censee contenir des blocs de 128 octets, et raler tres fort parce que l'adresse n'est pas multiple de 128...
In article <slrnjclh25.re9.jkb@rayleigh.systella.fr>,
JKB <jkb@koenigsberg.invalid> wrote:
Pas mal d'allocateurs modernes sont dits "a puissance de 2", et vont
betement agreger les allocations de taille similaire dans une meme page
memoire (et retrouver les infos de taille directement a partir de l'adresse).
Le gros avantage par rapport aux trucs antiques, c'est qu'il y a beaucoup
moins d'overhead pour les petites allocations...
Par contre, ceux-ci vont raler des qu'on leur passe une adresse qui ne colle
pas avec ce qu'ils s'attendent a avoir. Typiquement, si j'ai alloue 128
octets, et que je passe une adresse a +64, l'allocateur va determiner la
page, trouver que celle-ci est censee contenir des blocs de 128 octets,
et raler tres fort parce que l'adresse n'est pas multiple de 128...
Pas mal d'allocateurs modernes sont dits "a puissance de 2", et vont betement agreger les allocations de taille similaire dans une meme page memoire (et retrouver les infos de taille directement a partir de l'adresse).
Le gros avantage par rapport aux trucs antiques, c'est qu'il y a beaucoup moins d'overhead pour les petites allocations...
Par contre, ceux-ci vont raler des qu'on leur passe une adresse qui ne colle pas avec ce qu'ils s'attendent a avoir. Typiquement, si j'ai alloue 128 octets, et que je passe une adresse a +64, l'allocateur va determiner la page, trouver que celle-ci est censee contenir des blocs de 128 octets, et raler tres fort parce que l'adresse n'est pas multiple de 128...
erwan
(Marc Espie) écrivait :
Plus forcement, aujourd'hui.
Pas mal d'allocateurs modernes sont dits "a puissance de 2", et vont betement agreger les allocations de taille similaire dans une meme page memoire (et retrouver les infos de taille directement a partir de l'adresse).
Le gros avantage par rapport aux trucs antiques, c'est qu'il y a beaucoup moins d'overhead pour les petites allocations...
Et limiter la fragmentation mémoire, qui sur certains programmes peut avoir des effets désastreux (quand il reste 1Mo sous forme de 1000 blocs discontinus de 1Ko par exemple).
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
espie@lain.home (Marc Espie) écrivait :
Plus forcement, aujourd'hui.
Pas mal d'allocateurs modernes sont dits "a puissance de 2", et vont
betement agreger les allocations de taille similaire dans une meme page
memoire (et retrouver les infos de taille directement a partir de l'adresse).
Le gros avantage par rapport aux trucs antiques, c'est qu'il y a beaucoup
moins d'overhead pour les petites allocations...
Et limiter la fragmentation mémoire, qui sur certains programmes peut
avoir des effets désastreux (quand il reste 1Mo sous forme de 1000 blocs
discontinus de 1Ko par exemple).
--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
Pas mal d'allocateurs modernes sont dits "a puissance de 2", et vont betement agreger les allocations de taille similaire dans une meme page memoire (et retrouver les infos de taille directement a partir de l'adresse).
Le gros avantage par rapport aux trucs antiques, c'est qu'il y a beaucoup moins d'overhead pour les petites allocations...
Et limiter la fragmentation mémoire, qui sur certains programmes peut avoir des effets désastreux (quand il reste 1Mo sous forme de 1000 blocs discontinus de 1Ko par exemple).
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
JKB
Le Tue, 22 Nov 2011 08:46:48 +0100, écrivait :
(Marc Espie) écrivait :
Plus forcement, aujourd'hui.
Pas mal d'allocateurs modernes sont dits "a puissance de 2", et vont betement agreger les allocations de taille similaire dans une meme page memoire (et retrouver les infos de taille directement a partir de l'adresse).
Le gros avantage par rapport aux trucs antiques, c'est qu'il y a beaucoup moins d'overhead pour les petites allocations...
Et limiter la fragmentation mémoire, qui sur certains programmes peut avoir des effets désastreux (quand il reste 1Mo sous forme de 1000 blocs discontinus de 1Ko par exemple).
Oui, alors ça, lorsqu'on arrive à avoir de la fragmentation mémoire, c'est qu'on s'y est pris comme un pied et qu'on aurait dû utiliser un allocateur spécial (quitte à faire avec mmap()). Les allocateurs SLAB, qui allouent des blocs en puissance de deux, c'est sympathique, mais ça a aussi des limites amusantes. Il faut les dimensionner au plus juste si on veut être performant (pour ne pas se retrouver avec des blocs de 10 octets qui bouffent en réalité 4 Ko parce qu'il ne reste plus de blocs de taille adéquate...).
Personnellement, dans l'ordre, c'est malloc() (ptmalloc3), puis mmap(), puis vraiment lorsque je suis contraint à la faire un SLAB...
Le Tue, 22 Nov 2011 08:46:48 +0100,
erwan@rail.eu.org <erwan@rail.eu.org> écrivait :
espie@lain.home (Marc Espie) écrivait :
Plus forcement, aujourd'hui.
Pas mal d'allocateurs modernes sont dits "a puissance de 2", et vont
betement agreger les allocations de taille similaire dans une meme page
memoire (et retrouver les infos de taille directement a partir de l'adresse).
Le gros avantage par rapport aux trucs antiques, c'est qu'il y a beaucoup
moins d'overhead pour les petites allocations...
Et limiter la fragmentation mémoire, qui sur certains programmes peut
avoir des effets désastreux (quand il reste 1Mo sous forme de 1000 blocs
discontinus de 1Ko par exemple).
Oui, alors ça, lorsqu'on arrive à avoir de la fragmentation mémoire,
c'est qu'on s'y est pris comme un pied et qu'on aurait dû utiliser
un allocateur spécial (quitte à faire avec mmap()). Les allocateurs
SLAB, qui allouent des blocs en puissance de deux, c'est
sympathique, mais ça a aussi des limites amusantes. Il faut les
dimensionner au plus juste si on veut être performant (pour ne pas
se retrouver avec des blocs de 10 octets qui bouffent en réalité 4 Ko
parce qu'il ne reste plus de blocs de taille adéquate...).
Personnellement, dans l'ordre, c'est malloc() (ptmalloc3), puis mmap(),
puis vraiment lorsque je suis contraint à la faire un SLAB...
Cordialement,
JKB
--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Pas mal d'allocateurs modernes sont dits "a puissance de 2", et vont betement agreger les allocations de taille similaire dans une meme page memoire (et retrouver les infos de taille directement a partir de l'adresse).
Le gros avantage par rapport aux trucs antiques, c'est qu'il y a beaucoup moins d'overhead pour les petites allocations...
Et limiter la fragmentation mémoire, qui sur certains programmes peut avoir des effets désastreux (quand il reste 1Mo sous forme de 1000 blocs discontinus de 1Ko par exemple).
Oui, alors ça, lorsqu'on arrive à avoir de la fragmentation mémoire, c'est qu'on s'y est pris comme un pied et qu'on aurait dû utiliser un allocateur spécial (quitte à faire avec mmap()). Les allocateurs SLAB, qui allouent des blocs en puissance de deux, c'est sympathique, mais ça a aussi des limites amusantes. Il faut les dimensionner au plus juste si on veut être performant (pour ne pas se retrouver avec des blocs de 10 octets qui bouffent en réalité 4 Ko parce qu'il ne reste plus de blocs de taille adéquate...).
Personnellement, dans l'ordre, c'est malloc() (ptmalloc3), puis mmap(), puis vraiment lorsque je suis contraint à la faire un SLAB...