C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

realloc et templates

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Cyrille cns Szymanski
Guest





PostPosted: Sun Aug 17, 2003 11:07 pm    Post subject: realloc et templates Reply with quote



Bonjour,

Je voudrais créer un tableau d'objets (définis dans une template) de
taille variable. Il n'y a pas d'opérateur renew[], je me suis donc
rabattu sur realloc() et c'est ce qui est délicat.

Le problème est d'appeler correctement les constructeurs. Bizarrement
(pour moi), le code fonctionne pour les destructeurs mais pas les
constructeurs.

Voici une partie du code :

template <class Obj>
struct cnsBuffer
{
Obj *m_ptr; // le tableau d'objets
unsigned int m_nb; // la taille du tableau

int allocate( unsigned int nb )
{
FATAL( nb!=0 );

int ret=-1;

if( nb<m_nb )
{
// détruire les objets supprimés
for( unsigned int i=nb; i {
// ce bout de code fonctionne très bien
m_ptr[i].~Obj();
}
}

m_ptr = (Obj*)realloc( m_ptr, nb*sizeof(Obj) );
if( m_ptr!=0 )
{
// initialiser les nouveaux objets
for( unsigned int i=m_nb; i {
// celui là pose problème
m_ptr[i].Obj();
}
m_nb = nb;
ret = 0;
}
else
{
m_nb = 0;
ret = -1;
}

return ret;
}

};


Avec Borland C++ 5.5 j'obtiens l'erreur que dans l'expression "m_ptr
[i].Obj();" :

Structure required on left side of . or .* in function cnsBuffer
-> évidemment avec un char cela n'a pas de sens

'Obj' is not a member of 'TestClass' in function cnsBuffer
<TestClass>::allocate(unsigned int)
-> cette erreur me laisse perplexe, pourquoi le mécanisme de template ne
l'a pas traduit en TestClass() ?


En fait ma question est comment faire (proprement) ce que je cherche à
faire ?


J'ai aussi pensé à allouer un tableau temporaire avec new[] (dans le cas
où la taille augmente) puis le recopier dans la zone allouée par realloc
() et enfin le libérer avec free() pour ne pas appeler de destructeur,
mais c'est plutôt moche.


Merci d'avance pour votre aide,
--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/
Back to top
Fabien LE LEZ
Guest





PostPosted: Mon Aug 18, 2003 1:28 pm    Post subject: Re: realloc et templates Reply with quote



On 18 Aug 2003 12:52:11 GMT, "Cyrille "cns" Szymanski"
<cns2 (AT) cns (DOT) invalid> wrote:

Quote:
D'après ce que j'ai compris, il faut aussi doter la classe Obj de
l'opérateur
void *operator new(size_t s, Obj *a)

Ah ? T'es sûr ? Va falloir que je vérifie, mais je ne vois pas
pourquoi ça serait obligatoire.

Quote:
Franchement je ne vois pas pourquoi "m_ptr[i].~Obj();" fonctionne et pas
"m_ptr[i].Obj();".

"m_ptr[i].~Obj();" a un sens, puisque m_ptr[i] est un objet de classe
Obj, construit précédemment.
Par contre, quand tu écris "m_ptr[i].Obj();", m_ptr[i] n'est pas
encore un objet de classe Obj -- je vois mal comment ça pourrait avoir
un sens. Mais bon, a priori je me trompe quelque part -- je n'ai
jamais réussi à comprendre le fonctionnement des appels "directs" aux
constructeurs/destructeurs.


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Back to top
Fabien LE LEZ
Guest





PostPosted: Mon Aug 18, 2003 1:45 pm    Post subject: Re: realloc et templates Reply with quote



On 18 Aug 2003 13:40:08 GMT, "Cyrille "cns" Szymanski"
<cns2 (AT) cns (DOT) invalid> wrote:

Quote:
Oh, je dis ça parce que dans l'exemple suivant le compilateur

Quel compilateur utilises-tu ?
A noter que certains "vieux" compilos gèrent assez mal le "placement
new"...

Quote:
void main( void )

int main()


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Back to top
Patrick Mézard
Guest





PostPosted: Mon Aug 18, 2003 6:13 pm    Post subject: Re: realloc et templates Reply with quote

Quote:
Je voudrais créer un tableau d'objets (définis dans une template) de
taille variable. Il n'y a pas d'opérateur renew[], je me suis donc
rabattu sur realloc() et c'est ce qui est délicat.

Le problème est d'appeler correctement les constructeurs. Bizarrement
(pour moi), le code fonctionne pour les destructeurs mais pas les
constructeurs.

Tu peux jeter un coup d'oeil aux fonctions template std::unitialized_fill et
std::uninitialized_fill_n qui sont déclarées dans <memory>. A priori, ça
fait exactement ce que tu veux. Un peu de documentation à ce sujet :
http://www.sgi.com/tech/stl/uninitialized_fill.html
http://www.sgi.com/tech/stl/uninitialized_fill_n.html

Peut-être que l'implémentation fournie par Borland résoudra tes problèmes.
En plus, ça donne de bonnes garanties en cas de lancé d'exception lors de la
construction. Ce qui est un peu bizarre c'est qu'ils ne fournissent pas des
algorithmes similaires pour appeler les destructeurs.

Patrick Mézard



Back to top
Patrick Mézard
Guest





PostPosted: Tue Aug 19, 2003 6:44 am    Post subject: Re: realloc et templates Reply with quote


Quote:
Merci beaucoup pour ces infos. J'ai regardé l'implémentation de SGI et
j'en ai extrait quelques bouts intéressants. La doc SGI donne un exemple
d'utilisation de construct() qui est la base de cet algorithme.
Malheureusement il ne fonctionne pas sous Borland C++ 5.5. Le compilo
réclame un 'operator new(unsigned int,void *)'

D'après la documentation de SGI, "construct" est obsolète. L'idée c'était
plutôt de te servir des implémentations fournies par Borland (enfin
j'espère) dans <memory>. L'intérêt est que si jamais ces fonctions existent,
les #include nécessaires seront faits au niveau de <memory>.

Je pense à ça, parce que sous MSVC6 par exemple, il est nécessaire de faire
un #include <new> pour avoir des constructeurs des placement. Inspire toi
des headers de Borland, plutôt que du code de SGI, ils sont adaptés à ton
compilateur.

Patrick Mézard



Back to top
Cyrille cns Szymanski
Guest





PostPosted: Tue Aug 19, 2003 11:28 am    Post subject: Re: realloc et templates Reply with quote

Quote:
Je pense à ça, parce que sous MSVC6 par exemple, il est nécessaire de
faire un #include <new> pour avoir des constructeurs des placement.

Oui, c'est exactement ce qui me manquait. Dans mon cas et avec Borland, il
faut juste définir un extern new pour que ça marche.

extern void * operator new(size_t size, void* ptr);

La question que je me pose est de savoir pourquoi ? Est-ce pour permettre à
l'utilisateur de fournir son propre new ?

--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/

Back to top
Gabriel Dos Reis
Guest





PostPosted: Tue Aug 19, 2003 11:59 am    Post subject: Re: realloc et templates Reply with quote

"Cyrille "cns" Szymanski" <cns2 (AT) cns (DOT) invalid> writes:

Quote:
La question que je me pose est de savoir pourquoi ?

es-tu sûr de vouloir savoir ?

-- Gaby

Back to top
Gabriel Dos Reis
Guest





PostPosted: Tue Aug 19, 2003 3:31 pm    Post subject: Re: realloc et templates Reply with quote

"Cyrille "cns" Szymanski" <cns2 (AT) cns (DOT) invalid> writes:

Quote:
| La question que je me pose est de savoir pourquoi ?

es-tu sûr de vouloir savoir ?

J'ai dû dire quelquechose qui t'a fâché, non ?


Non. Aucunément. C'était ma façon de dire que si tu ne maîtrises pas
encore les fonctionnalités simples (je ne considère pas la gestion de
mémoire ainsi que la « magie » derrière new/delete comme simple)
alors, tu seras probablement confus par une explication detaillée du
pourquoi et comment du new. D'ailleurs ce que j'ai dit était très
sommaire et j'ai escamoté beaucoup de détails.

-- Gaby



Back to top
drkm
Guest





PostPosted: Mon Aug 25, 2003 6:47 am    Post subject: Re: realloc et templates Reply with quote

Fabien LE LEZ <gramster (AT) gramster (DOT) com> writes:

Quote:
Il faut utiliser le new de position (placement new). De mémoire (je
l'utilise peu), il faut faire :

new (m_ptr[i]) Obj;

Ne serait-ce pas plutôt :

new ( & m_ptr[i] ) Obj ;

ou, au choix :

new ( m_ptr + i ) Obj ;

Il me semble que le placement new demande une adresse, et non une
référence.

--drkm

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.