Jean-Marc Bourguet wrote on 20/11/2006 20:40:* Dans le cas de new[] et delete[], le compilateur doit stocker le nombre
d'éléments alloués pour pouvoir faire ces appels. Le premier endroit qui
me vient à l'esprit, c'est d'allouer la taille d'un int (ou plus pour des
raisons d'alignement) en plus et de mettre ce nombre en tête de bloc.
depuis des lustres, l'allocation prends 8 octets (sur archi. 32 bits) de
plus que demandée, un long pour stocker la taille d'un élément, un long
pour le nombre d'éléments; le ptr retourné est sur le bloc alloué + 8.
(Comme ce nombre est inutile dans le cas des POD, ça ne m'étonnerait pas
non pas inutile, le bloc à libérer est toujours n * taille élement -- la
méthode concrête reçoit un void*, elle ne peut plus faire de sizeof ou
autre astuce, elle dépend nécessairement des infos du "header masqué".
non plus qu'un compilateur optimise en le supprimant dans ce cas là,
auquel cas en effet l'appel à delete plutôt que delete[] pourrait passer
inapperçu jusqu'à l'ajout d'un destructeur ou l'implémentation d'une
autre politique d'allocation pour les tableaux...)
je ne pense pas qu'il est intérêt à virer ces infos, par contre il ne
fait rien de spécial sinon de libérer le bloc.
dans le cas d'instances, il doit appeler le destructeur sur chaque item et
peut faire des contrôles de heap plus poussés (pour par exemple justement
détecter des erreurs dans ces destructeurs) Studio fait cela en mode Debug
et un delete à la place d'un delete [] envoie aussitôt au purgatoire.
Jean-Marc Bourguet wrote on 20/11/2006 20:40:
* Dans le cas de new[] et delete[], le compilateur doit stocker le nombre
d'éléments alloués pour pouvoir faire ces appels. Le premier endroit qui
me vient à l'esprit, c'est d'allouer la taille d'un int (ou plus pour des
raisons d'alignement) en plus et de mettre ce nombre en tête de bloc.
depuis des lustres, l'allocation prends 8 octets (sur archi. 32 bits) de
plus que demandée, un long pour stocker la taille d'un élément, un long
pour le nombre d'éléments; le ptr retourné est sur le bloc alloué + 8.
(Comme ce nombre est inutile dans le cas des POD, ça ne m'étonnerait pas
non pas inutile, le bloc à libérer est toujours n * taille élement -- la
méthode concrête reçoit un void*, elle ne peut plus faire de sizeof ou
autre astuce, elle dépend nécessairement des infos du "header masqué".
non plus qu'un compilateur optimise en le supprimant dans ce cas là,
auquel cas en effet l'appel à delete plutôt que delete[] pourrait passer
inapperçu jusqu'à l'ajout d'un destructeur ou l'implémentation d'une
autre politique d'allocation pour les tableaux...)
je ne pense pas qu'il est intérêt à virer ces infos, par contre il ne
fait rien de spécial sinon de libérer le bloc.
dans le cas d'instances, il doit appeler le destructeur sur chaque item et
peut faire des contrôles de heap plus poussés (pour par exemple justement
détecter des erreurs dans ces destructeurs) Studio fait cela en mode Debug
et un delete à la place d'un delete [] envoie aussitôt au purgatoire.
Jean-Marc Bourguet wrote on 20/11/2006 20:40:* Dans le cas de new[] et delete[], le compilateur doit stocker le nombre
d'éléments alloués pour pouvoir faire ces appels. Le premier endroit qui
me vient à l'esprit, c'est d'allouer la taille d'un int (ou plus pour des
raisons d'alignement) en plus et de mettre ce nombre en tête de bloc.
depuis des lustres, l'allocation prends 8 octets (sur archi. 32 bits) de
plus que demandée, un long pour stocker la taille d'un élément, un long
pour le nombre d'éléments; le ptr retourné est sur le bloc alloué + 8.
(Comme ce nombre est inutile dans le cas des POD, ça ne m'étonnerait pas
non pas inutile, le bloc à libérer est toujours n * taille élement -- la
méthode concrête reçoit un void*, elle ne peut plus faire de sizeof ou
autre astuce, elle dépend nécessairement des infos du "header masqué".
non plus qu'un compilateur optimise en le supprimant dans ce cas là,
auquel cas en effet l'appel à delete plutôt que delete[] pourrait passer
inapperçu jusqu'à l'ajout d'un destructeur ou l'implémentation d'une
autre politique d'allocation pour les tableaux...)
je ne pense pas qu'il est intérêt à virer ces infos, par contre il ne
fait rien de spécial sinon de libérer le bloc.
dans le cas d'instances, il doit appeler le destructeur sur chaque item et
peut faire des contrôles de heap plus poussés (pour par exemple justement
détecter des erreurs dans ces destructeurs) Studio fait cela en mode Debug
et un delete à la place d'un delete [] envoie aussitôt au purgatoire.
Jean-Marc Bourguet wrote on 20/11/2006 20:40:* Dans le cas de new[] et delete[], le compilateur doit stocker le nomb re
d'éléments alloués pour pouvoir faire ces appels. Le premier e ndroit qui
me vient à l'esprit, c'est d'allouer la taille d'un int (ou plus po ur des
raisons d'alignement) en plus et de mettre ce nombre en tête de blo c.
depuis des lustres, l'allocation prends 8 octets (sur archi. 32 bits) de
plus que demandée, un long pour stocker la taille d'un élément, un long
pour le nombre d'éléments; le ptr retourné est sur le bloc alloué + 8.
(Comme ce nombre est inutile dans le cas des POD, ça ne
m'étonnerait pas
non pas inutile, le bloc à libérer est toujours n * taille élement -- la
méthode concrête reçoit un void*, elle ne peut plus faire de sizeof ou
autre astuce, elle dépend nécessairement des infos du "header masqu é".
non plus qu'un compilateur optimise en le supprimant dans ce cas là,
auquel cas en effet l'appel à delete plutôt que delete[] pourrait passer
inapperçu jusqu'à l'ajout d'un destructeur ou l'implémentation d'une
autre politique d'allocation pour les tableaux...)
je ne pense pas qu'il est intérêt à virer ces infos, par contre il ne
fait rien de spécial sinon de libérer le bloc.
dans le cas d'instances, il doit appeler le destructeur sur chaque item
et peut faire des contrôles de heap plus poussés (pour par exemple
justement détecter des erreurs dans ces destructeurs) Studio fait cela
en mode Debug et un delete à la place d'un delete [] envoie aussitôt au
purgatoire.
Jean-Marc Bourguet wrote on 20/11/2006 20:40:
* Dans le cas de new[] et delete[], le compilateur doit stocker le nomb re
d'éléments alloués pour pouvoir faire ces appels. Le premier e ndroit qui
me vient à l'esprit, c'est d'allouer la taille d'un int (ou plus po ur des
raisons d'alignement) en plus et de mettre ce nombre en tête de blo c.
depuis des lustres, l'allocation prends 8 octets (sur archi. 32 bits) de
plus que demandée, un long pour stocker la taille d'un élément, un long
pour le nombre d'éléments; le ptr retourné est sur le bloc alloué + 8.
(Comme ce nombre est inutile dans le cas des POD, ça ne
m'étonnerait pas
non pas inutile, le bloc à libérer est toujours n * taille élement -- la
méthode concrête reçoit un void*, elle ne peut plus faire de sizeof ou
autre astuce, elle dépend nécessairement des infos du "header masqu é".
non plus qu'un compilateur optimise en le supprimant dans ce cas là,
auquel cas en effet l'appel à delete plutôt que delete[] pourrait passer
inapperçu jusqu'à l'ajout d'un destructeur ou l'implémentation d'une
autre politique d'allocation pour les tableaux...)
je ne pense pas qu'il est intérêt à virer ces infos, par contre il ne
fait rien de spécial sinon de libérer le bloc.
dans le cas d'instances, il doit appeler le destructeur sur chaque item
et peut faire des contrôles de heap plus poussés (pour par exemple
justement détecter des erreurs dans ces destructeurs) Studio fait cela
en mode Debug et un delete à la place d'un delete [] envoie aussitôt au
purgatoire.
Jean-Marc Bourguet wrote on 20/11/2006 20:40:* Dans le cas de new[] et delete[], le compilateur doit stocker le nomb re
d'éléments alloués pour pouvoir faire ces appels. Le premier e ndroit qui
me vient à l'esprit, c'est d'allouer la taille d'un int (ou plus po ur des
raisons d'alignement) en plus et de mettre ce nombre en tête de blo c.
depuis des lustres, l'allocation prends 8 octets (sur archi. 32 bits) de
plus que demandée, un long pour stocker la taille d'un élément, un long
pour le nombre d'éléments; le ptr retourné est sur le bloc alloué + 8.
(Comme ce nombre est inutile dans le cas des POD, ça ne
m'étonnerait pas
non pas inutile, le bloc à libérer est toujours n * taille élement -- la
méthode concrête reçoit un void*, elle ne peut plus faire de sizeof ou
autre astuce, elle dépend nécessairement des infos du "header masqu é".
non plus qu'un compilateur optimise en le supprimant dans ce cas là,
auquel cas en effet l'appel à delete plutôt que delete[] pourrait passer
inapperçu jusqu'à l'ajout d'un destructeur ou l'implémentation d'une
autre politique d'allocation pour les tableaux...)
je ne pense pas qu'il est intérêt à virer ces infos, par contre il ne
fait rien de spécial sinon de libérer le bloc.
dans le cas d'instances, il doit appeler le destructeur sur chaque item
et peut faire des contrôles de heap plus poussés (pour par exemple
justement détecter des erreurs dans ces destructeurs) Studio fait cela
en mode Debug et un delete à la place d'un delete [] envoie aussitôt au
purgatoire.
C'est une technique courante, popularisee par K&R, mais ce n'est pas la
seule.
Ce n'est d'ailleurs pas ce dont je parlais. Je parlais de la necessite de
stocker le nombre d'element dans le tableau alloue d'une facon connue par
le compilateur.
[...]
Tiens, il se passe exactement ce que j'ai ecrit avec g++ et sun CC. Un
appel a delete plutot que delete[] peut passer inappercu pour un tableau de
char, il a peut de chance de passer inappercu pour un tableau de string.
C'est une technique courante, popularisee par K&R, mais ce n'est pas la
seule.
Ce n'est d'ailleurs pas ce dont je parlais. Je parlais de la necessite de
stocker le nombre d'element dans le tableau alloue d'une facon connue par
le compilateur.
[...]
Tiens, il se passe exactement ce que j'ai ecrit avec g++ et sun CC. Un
appel a delete plutot que delete[] peut passer inappercu pour un tableau de
char, il a peut de chance de passer inappercu pour un tableau de string.
C'est une technique courante, popularisee par K&R, mais ce n'est pas la
seule.
Ce n'est d'ailleurs pas ce dont je parlais. Je parlais de la necessite de
stocker le nombre d'element dans le tableau alloue d'une facon connue par
le compilateur.
[...]
Tiens, il se passe exactement ce que j'ai ecrit avec g++ et sun CC. Un
appel a delete plutot que delete[] peut passer inappercu pour un tableau de
char, il a peut de chance de passer inappercu pour un tableau de string.
Jean-Marc Bourguet wrote on 21/11/2006 09:21:Ce n'est d'ailleurs pas ce dont je parlais. Je parlais de la necessite de
stocker le nombre d'element dans le tableau alloue d'une facon connue par
le compilateur.
ah pardon, moi je parlais de la façon dont le compilo stocke le nombre
d'éléments alloués ?!...
depuis des lustres, l'allocation prends 8 octets (sur archi. 32 bits)
de plus que demandée, un long pour stocker la taille d'un élément, un
long pour le nombre d'éléments; le ptr retourné est sur le bloc alloué
+ 8.
[...]
Tiens, il se passe exactement ce que j'ai ecrit avec g++ et sun CC. Un
appel a delete plutot que delete[] peut passer inappercu pour un tableau de
char, il a peut de chance de passer inappercu pour un tableau de string.
c'est ce que j'ai dit, un type primitive (un POD) ne créé aucune
différence;
pour des instances, un compilo un peu plus répandu comme vc détecte
l'erreur au runtime et ne peut pas laisser (sauf à ne rien débugger)
l'erreur inaperçue.
Jean-Marc Bourguet wrote on 21/11/2006 09:21:
Ce n'est d'ailleurs pas ce dont je parlais. Je parlais de la necessite de
stocker le nombre d'element dans le tableau alloue d'une facon connue par
le compilateur.
ah pardon, moi je parlais de la façon dont le compilo stocke le nombre
d'éléments alloués ?!...
depuis des lustres, l'allocation prends 8 octets (sur archi. 32 bits)
de plus que demandée, un long pour stocker la taille d'un élément, un
long pour le nombre d'éléments; le ptr retourné est sur le bloc alloué
+ 8.
[...]
Tiens, il se passe exactement ce que j'ai ecrit avec g++ et sun CC. Un
appel a delete plutot que delete[] peut passer inappercu pour un tableau de
char, il a peut de chance de passer inappercu pour un tableau de string.
c'est ce que j'ai dit, un type primitive (un POD) ne créé aucune
différence;
pour des instances, un compilo un peu plus répandu comme vc détecte
l'erreur au runtime et ne peut pas laisser (sauf à ne rien débugger)
l'erreur inaperçue.
Jean-Marc Bourguet wrote on 21/11/2006 09:21:Ce n'est d'ailleurs pas ce dont je parlais. Je parlais de la necessite de
stocker le nombre d'element dans le tableau alloue d'une facon connue par
le compilateur.
ah pardon, moi je parlais de la façon dont le compilo stocke le nombre
d'éléments alloués ?!...
depuis des lustres, l'allocation prends 8 octets (sur archi. 32 bits)
de plus que demandée, un long pour stocker la taille d'un élément, un
long pour le nombre d'éléments; le ptr retourné est sur le bloc alloué
+ 8.
[...]
Tiens, il se passe exactement ce que j'ai ecrit avec g++ et sun CC. Un
appel a delete plutot que delete[] peut passer inappercu pour un tableau de
char, il a peut de chance de passer inappercu pour un tableau de string.
c'est ce que j'ai dit, un type primitive (un POD) ne créé aucune
différence;
pour des instances, un compilo un peu plus répandu comme vc détecte
l'erreur au runtime et ne peut pas laisser (sauf à ne rien débugger)
l'erreur inaperçue.
Jean-Marc Bourguet wrote on 21/11/2006 22:06:Effectivement, je t'ai lu trop vite. Nous ne sommes même plus d'accord
sur
le premier point. Reprenons ce que tu as écrit:
te me rassures ;)[...]
intéressant mais très implémentation (CRT) dépendant et:
1- loin de la question initiale (et je me place à ce niveau, savoir le bit
et le byte de ce qui est stocké par qui et où n'était pas indispensable),
ou alors ...
2- mais ne dit pas pourquoi, concrêtement, un type primitif marche et pas
un array d'instance, explique-nous quelles infos sont requises (l'adresse
d'une tabmle de meth. virt., l'adresse d'un destructeur particulier, un
typeof, ???) et comment on-sait-pas-qui (pas ton opérateur qui ne fait que
::free()) itère les instances pour appeler chaque destructeur.
Tu as fait attention à la trace que j'ai donnée? Un POD se comporte de
manière différente avec les deux compilateurs que j'ai essayé.
et ? rapelle-moi CC est utilisé pour quel % des applis in-the-field?
il est toujours possible (et parfois facile) de trouver un contre-exemple
mais si celui-ci est peu fréquent ou inexistant pour qui cherchait une
explication, cela n'explique rien.
D'après ce que j'ai cru comprendre des discussions lancées par des gens
utilisant VC++ et ayant des problèmes, ce qu'il fait c'est utiliser des
macros pour substituer aux appels à new et new[] des appels à un new/new[]
avec placement pour fournir des d'informations pour un allocateur de debug.
non pas vraiment, je distinguerais:
Jean-Marc Bourguet wrote on 21/11/2006 22:06:
Effectivement, je t'ai lu trop vite. Nous ne sommes même plus d'accord
sur
le premier point. Reprenons ce que tu as écrit:
te me rassures ;)
[...]
intéressant mais très implémentation (CRT) dépendant et:
1- loin de la question initiale (et je me place à ce niveau, savoir le bit
et le byte de ce qui est stocké par qui et où n'était pas indispensable),
ou alors ...
2- mais ne dit pas pourquoi, concrêtement, un type primitif marche et pas
un array d'instance, explique-nous quelles infos sont requises (l'adresse
d'une tabmle de meth. virt., l'adresse d'un destructeur particulier, un
typeof, ???) et comment on-sait-pas-qui (pas ton opérateur qui ne fait que
::free()) itère les instances pour appeler chaque destructeur.
Tu as fait attention à la trace que j'ai donnée? Un POD se comporte de
manière différente avec les deux compilateurs que j'ai essayé.
et ? rapelle-moi CC est utilisé pour quel % des applis in-the-field?
il est toujours possible (et parfois facile) de trouver un contre-exemple
mais si celui-ci est peu fréquent ou inexistant pour qui cherchait une
explication, cela n'explique rien.
D'après ce que j'ai cru comprendre des discussions lancées par des gens
utilisant VC++ et ayant des problèmes, ce qu'il fait c'est utiliser des
macros pour substituer aux appels à new et new[] des appels à un new/new[]
avec placement pour fournir des d'informations pour un allocateur de debug.
non pas vraiment, je distinguerais:
Jean-Marc Bourguet wrote on 21/11/2006 22:06:Effectivement, je t'ai lu trop vite. Nous ne sommes même plus d'accord
sur
le premier point. Reprenons ce que tu as écrit:
te me rassures ;)[...]
intéressant mais très implémentation (CRT) dépendant et:
1- loin de la question initiale (et je me place à ce niveau, savoir le bit
et le byte de ce qui est stocké par qui et où n'était pas indispensable),
ou alors ...
2- mais ne dit pas pourquoi, concrêtement, un type primitif marche et pas
un array d'instance, explique-nous quelles infos sont requises (l'adresse
d'une tabmle de meth. virt., l'adresse d'un destructeur particulier, un
typeof, ???) et comment on-sait-pas-qui (pas ton opérateur qui ne fait que
::free()) itère les instances pour appeler chaque destructeur.
Tu as fait attention à la trace que j'ai donnée? Un POD se comporte de
manière différente avec les deux compilateurs que j'ai essayé.
et ? rapelle-moi CC est utilisé pour quel % des applis in-the-field?
il est toujours possible (et parfois facile) de trouver un contre-exemple
mais si celui-ci est peu fréquent ou inexistant pour qui cherchait une
explication, cela n'explique rien.
D'après ce que j'ai cru comprendre des discussions lancées par des gens
utilisant VC++ et ayant des problèmes, ce qu'il fait c'est utiliser des
macros pour substituer aux appels à new et new[] des appels à un new/new[]
avec placement pour fournir des d'informations pour un allocateur de debug.
non pas vraiment, je distinguerais:
Une technique possible (utilisée visiblement par g++ et Sun CC; j'ai en
fait du mal à en imaginer une autre qui tienne la route) est d'allouer en
plus un espace pour le socker avant le tableau et d'ajuster le résultat de
l'opérateur new[]. Cet espace supplémentaire n'est pas nécessaire dans le
cas des POD: ceux n'ayant pas de destructeur, le code généré n'a pa s besoin
de connaître le nombre d'élements.
pour des instances, un compilo un peu plus répandu comme vc détecte
l'erreur au runtime et ne peut pas laisser (sauf à ne rien débugger)
l'erreur inaperçue.
D'après ce que j'ai cru comprendre des discussions lancées par des ge ns
utilisant VC++ et ayant des problèmes, ce qu'il fait c'est utiliser des
macros pour substituer aux appels à new et new[] des appels à un new/ new[]
avec placement pour fournir des d'informations pour un allocateur de debu g.
Si j'ai bien compris, il aurait été plus robuste de fournir une
bibliothèque contenant un allocateur de debug qui socke l'adresse de
l'appelant et se sert des maps de l'édition de liens et autres informat ions
de debug pour récupérer l'information cherchée.
Sun fournit une telle bibliothèque. On peut s'en faire une
sans problème pour gcc car il fournit les primitives
nécessaires.
Une technique possible (utilisée visiblement par g++ et Sun CC; j'ai en
fait du mal à en imaginer une autre qui tienne la route) est d'allouer en
plus un espace pour le socker avant le tableau et d'ajuster le résultat de
l'opérateur new[]. Cet espace supplémentaire n'est pas nécessaire dans le
cas des POD: ceux n'ayant pas de destructeur, le code généré n'a pa s besoin
de connaître le nombre d'élements.
pour des instances, un compilo un peu plus répandu comme vc détecte
l'erreur au runtime et ne peut pas laisser (sauf à ne rien débugger)
l'erreur inaperçue.
D'après ce que j'ai cru comprendre des discussions lancées par des ge ns
utilisant VC++ et ayant des problèmes, ce qu'il fait c'est utiliser des
macros pour substituer aux appels à new et new[] des appels à un new/ new[]
avec placement pour fournir des d'informations pour un allocateur de debu g.
Si j'ai bien compris, il aurait été plus robuste de fournir une
bibliothèque contenant un allocateur de debug qui socke l'adresse de
l'appelant et se sert des maps de l'édition de liens et autres informat ions
de debug pour récupérer l'information cherchée.
Sun fournit une telle bibliothèque. On peut s'en faire une
sans problème pour gcc car il fournit les primitives
nécessaires.
Une technique possible (utilisée visiblement par g++ et Sun CC; j'ai en
fait du mal à en imaginer une autre qui tienne la route) est d'allouer en
plus un espace pour le socker avant le tableau et d'ajuster le résultat de
l'opérateur new[]. Cet espace supplémentaire n'est pas nécessaire dans le
cas des POD: ceux n'ayant pas de destructeur, le code généré n'a pa s besoin
de connaître le nombre d'élements.
pour des instances, un compilo un peu plus répandu comme vc détecte
l'erreur au runtime et ne peut pas laisser (sauf à ne rien débugger)
l'erreur inaperçue.
D'après ce que j'ai cru comprendre des discussions lancées par des ge ns
utilisant VC++ et ayant des problèmes, ce qu'il fait c'est utiliser des
macros pour substituer aux appels à new et new[] des appels à un new/ new[]
avec placement pour fournir des d'informations pour un allocateur de debu g.
Si j'ai bien compris, il aurait été plus robuste de fournir une
bibliothèque contenant un allocateur de debug qui socke l'adresse de
l'appelant et se sert des maps de l'édition de liens et autres informat ions
de debug pour récupérer l'information cherchée.
Sun fournit une telle bibliothèque. On peut s'en faire une
sans problème pour gcc car il fournit les primitives
nécessaires.
Jean-Marc Bourguet wrote on 21/11/2006 22:06:[...]
Tu as fait attention à la trace que j'ai donnée? Un POD se comport e de
manière différente avec les deux compilateurs que j'ai essayé.
et ? rapelle-moi CC est utilisé pour quel % des applis in-the-field?
il est toujours possible (et parfois facile) de trouver un
contre-exemple mais si celui-ci est peu fréquent ou inexistant pour qui
cherchait une explication, cela n'explique rien.
Jean-Marc Bourguet wrote on 21/11/2006 22:06:
[...]
Tu as fait attention à la trace que j'ai donnée? Un POD se comport e de
manière différente avec les deux compilateurs que j'ai essayé.
et ? rapelle-moi CC est utilisé pour quel % des applis in-the-field?
il est toujours possible (et parfois facile) de trouver un
contre-exemple mais si celui-ci est peu fréquent ou inexistant pour qui
cherchait une explication, cela n'explique rien.
Jean-Marc Bourguet wrote on 21/11/2006 22:06:[...]
Tu as fait attention à la trace que j'ai donnée? Un POD se comport e de
manière différente avec les deux compilateurs que j'ai essayé.
et ? rapelle-moi CC est utilisé pour quel % des applis in-the-field?
il est toujours possible (et parfois facile) de trouver un
contre-exemple mais si celui-ci est peu fréquent ou inexistant pour qui
cherchait une explication, cela n'explique rien.
Jean-Marc Bourguet wrote:
[...]Une technique possible (utilisée visiblement par g++ et Sun CC;
j'ai en fait du mal à en imaginer une autre qui tienne la route)
est d'allouer en plus un espace pour le socker avant le tableau et
d'ajuster le résultat de l'opérateur new[]. Cet espace
supplémentaire n'est pas nécessaire dans le cas des POD: ceux
n'ayant pas de destructeur, le code généré n'a pas besoin de
connaître le nombre d'élements.
À part reserver de la place en tête, et stocker les informations là,
je ne vois effectivement pas d'autre solution réaliste. (On parle
parfois de mettre les informations dans un tableau indicé par
l'adresse, genre std::map ou std::unordered_map, mais je n'ai jamais
entendu parler d'une implémentation qui le fait réelement.)
Jean-Marc Bourguet wrote:
[...]
Une technique possible (utilisée visiblement par g++ et Sun CC;
j'ai en fait du mal à en imaginer une autre qui tienne la route)
est d'allouer en plus un espace pour le socker avant le tableau et
d'ajuster le résultat de l'opérateur new[]. Cet espace
supplémentaire n'est pas nécessaire dans le cas des POD: ceux
n'ayant pas de destructeur, le code généré n'a pas besoin de
connaître le nombre d'élements.
À part reserver de la place en tête, et stocker les informations là,
je ne vois effectivement pas d'autre solution réaliste. (On parle
parfois de mettre les informations dans un tableau indicé par
l'adresse, genre std::map ou std::unordered_map, mais je n'ai jamais
entendu parler d'une implémentation qui le fait réelement.)
Jean-Marc Bourguet wrote:
[...]Une technique possible (utilisée visiblement par g++ et Sun CC;
j'ai en fait du mal à en imaginer une autre qui tienne la route)
est d'allouer en plus un espace pour le socker avant le tableau et
d'ajuster le résultat de l'opérateur new[]. Cet espace
supplémentaire n'est pas nécessaire dans le cas des POD: ceux
n'ayant pas de destructeur, le code généré n'a pas besoin de
connaître le nombre d'élements.
À part reserver de la place en tête, et stocker les informations là,
je ne vois effectivement pas d'autre solution réaliste. (On parle
parfois de mettre les informations dans un tableau indicé par
l'adresse, genre std::map ou std::unordered_map, mais je n'ai jamais
entendu parler d'une implémentation qui le fait réelement.)
On a repondu a la question initiale. La question en cours est celle de
Jean-Marc Desperrier: << Justement la plupart des implémentations
"pardonnent" cette erreur et font ce qu'il faut même avec le mauvais appel,
non ? >>
Une expression
T* p = new T[10];
s'execute en deux phases [...]
De meme
delete[] p;
s'execute en deux phases [...]
L'utilisateur peut remplacer ::operator new[] et ::operator delete[], donc
la zone de stockage du 10 ne peut pas se trouver dans les entetes utilises
eventuellement par les allocateurs, meme si ceux-ci ont de la place libre a
cause des contraintes d'alignement.
As-tu fait tourner mon exemple avec VC++ puisque tu as l'air de considerer
tout le reste comme peu frequent ou inexistant?
On a repondu a la question initiale. La question en cours est celle de
Jean-Marc Desperrier: << Justement la plupart des implémentations
"pardonnent" cette erreur et font ce qu'il faut même avec le mauvais appel,
non ? >>
Une expression
T* p = new T[10];
s'execute en deux phases [...]
De meme
delete[] p;
s'execute en deux phases [...]
L'utilisateur peut remplacer ::operator new[] et ::operator delete[], donc
la zone de stockage du 10 ne peut pas se trouver dans les entetes utilises
eventuellement par les allocateurs, meme si ceux-ci ont de la place libre a
cause des contraintes d'alignement.
As-tu fait tourner mon exemple avec VC++ puisque tu as l'air de considerer
tout le reste comme peu frequent ou inexistant?
On a repondu a la question initiale. La question en cours est celle de
Jean-Marc Desperrier: << Justement la plupart des implémentations
"pardonnent" cette erreur et font ce qu'il faut même avec le mauvais appel,
non ? >>
Une expression
T* p = new T[10];
s'execute en deux phases [...]
De meme
delete[] p;
s'execute en deux phases [...]
L'utilisateur peut remplacer ::operator new[] et ::operator delete[], donc
la zone de stockage du 10 ne peut pas se trouver dans les entetes utilises
eventuellement par les allocateurs, meme si ceux-ci ont de la place libre a
cause des contraintes d'alignement.
As-tu fait tourner mon exemple avec VC++ puisque tu as l'air de considerer
tout le reste comme peu frequent ou inexistant?
Seulement, un essai rapide avec VC++ (celui du Studio 2005)
montre qu'il ne réserve que quatre octets [...]
Du coup, je me démande de quoi parlait Sylvain réelement.
D'après ce que j'ai cru comprendre des discussions lancées par des gens
utilisant VC++ et ayant des problèmes, ce qu'il fait c'est utiliser des
macros pour substituer aux appels à new et new[] des appels à un new/new[]
avec placement pour fournir des d'informations pour un allocateur de debug.
Je ne crois pas. En tout cas, il accepte des new de placement,
ce qui pose des problèmes avec des macros.
Si j'ai bien compris, il aurait été plus robuste de fournir une
bibliothèque contenant un allocateur de debug qui socke l'adresse de
l'appelant et se sert des maps de l'édition de liens et autres informations
de debug pour récupérer l'information cherchée.
C'est ce qu'il font. Le problème, c'est que par défaut, on linke
cette bibliothèque statiquement avec chaque .dll, et que chaque
..dll utilise sa propre version (un peu comme si on utilisait des
link map sous Solaris, et que les adresses de malloc et de free
n'était pas exportées).
Du coup, si un des .dll est linké avec
la version debug, et un autre non, on a des problèmes si la
mémoire est allouée dans un .dll, et libérée dans un autre.
Seulement, un essai rapide avec VC++ (celui du Studio 2005)
montre qu'il ne réserve que quatre octets [...]
Du coup, je me démande de quoi parlait Sylvain réelement.
D'après ce que j'ai cru comprendre des discussions lancées par des gens
utilisant VC++ et ayant des problèmes, ce qu'il fait c'est utiliser des
macros pour substituer aux appels à new et new[] des appels à un new/new[]
avec placement pour fournir des d'informations pour un allocateur de debug.
Je ne crois pas. En tout cas, il accepte des new de placement,
ce qui pose des problèmes avec des macros.
Si j'ai bien compris, il aurait été plus robuste de fournir une
bibliothèque contenant un allocateur de debug qui socke l'adresse de
l'appelant et se sert des maps de l'édition de liens et autres informations
de debug pour récupérer l'information cherchée.
C'est ce qu'il font. Le problème, c'est que par défaut, on linke
cette bibliothèque statiquement avec chaque .dll, et que chaque
..dll utilise sa propre version (un peu comme si on utilisait des
link map sous Solaris, et que les adresses de malloc et de free
n'était pas exportées).
Du coup, si un des .dll est linké avec
la version debug, et un autre non, on a des problèmes si la
mémoire est allouée dans un .dll, et libérée dans un autre.
Seulement, un essai rapide avec VC++ (celui du Studio 2005)
montre qu'il ne réserve que quatre octets [...]
Du coup, je me démande de quoi parlait Sylvain réelement.
D'après ce que j'ai cru comprendre des discussions lancées par des gens
utilisant VC++ et ayant des problèmes, ce qu'il fait c'est utiliser des
macros pour substituer aux appels à new et new[] des appels à un new/new[]
avec placement pour fournir des d'informations pour un allocateur de debug.
Je ne crois pas. En tout cas, il accepte des new de placement,
ce qui pose des problèmes avec des macros.
Si j'ai bien compris, il aurait été plus robuste de fournir une
bibliothèque contenant un allocateur de debug qui socke l'adresse de
l'appelant et se sert des maps de l'édition de liens et autres informations
de debug pour récupérer l'information cherchée.
C'est ce qu'il font. Le problème, c'est que par défaut, on linke
cette bibliothèque statiquement avec chaque .dll, et que chaque
..dll utilise sa propre version (un peu comme si on utilisait des
link map sous Solaris, et que les adresses de malloc et de free
n'était pas exportées).
Du coup, si un des .dll est linké avec
la version debug, et un autre non, on a des problèmes si la
mémoire est allouée dans un .dll, et libérée dans un autre.