[orbitcpp-list] Re: C++ mapping of OUT variable-length structures
Status: Beta
Brought to you by:
philipd
From: Diego S. R. <dse...@di...> - 2002-04-24 19:53:23
|
Hi! On Wed, Apr 24, 2002 at 09:31:55PM +0200, ERDI Gergo wrote: | On Wed, 24 Apr 2002, Diego Sevilla Ruiz wrote: |=20 | > | So this is useful when you pass in (on the caller side) a non-empty | > | structure, right? | >=20 | > Hmmm... I can't understand what you mean by a non-empty structure... | > This has nothing to do with either if the structure is empty or | > non-empty... (and I don't see the need for an empty structure either.= ..) |=20 | OK so let's talk about actual code here. |=20 | Suppose I have the following on the client side: |=20 | Test::Test_st *strct; | master_ptr->foo (strct); | // Do stuff on strct | delete strct; OK. |=20 | The signature of foo is, according to this _out convention: |=20 | void foo (Test::Test_st_out struct_out); |=20 | So in the above example, when master_ptr->foo returns, struct_out point= s | to a valid structure, right? |=20 | So, what happens when instead, the following is done: |=20 | Test::Test_st *strct =3D new Test::Test_st; | // Fill strct | // Use it as an IN parameter | other_ptr->other_method (*strct); | =09 | master_ptr->foo (strct); |=20 | delete strct; |=20 So you are leaking memory here. That of the previous "new" allocated struct.=20 The correct code is to either=20 1. use Test::Test_st_var struct or 2. add a delete struct *after* other_method and *before* foo call. | Will master_ptr->foo in this case delete the old strct first? No, it wont. It will free it *only* if you are using a _var variable. | Or is this | simply something that shouldn't be done? If it shouldn't be done, then = I, | again, don't understand what the _out class is supposed to do: you coul= d | use vanilla Test::Test_st*&'s as the OUT argument type and do the same. |=20 OK. Let's go deeper in detail ;-) It actually works OK if you only use pointers, but let's assume that you're using _var classes, that is: Test::Test_st_var st =3D new Test::Test_st(); OK. Then, if you've declared the method foo as: foo( Test::Test_st*& t_out) and you call foo ( st ) , then this is what happens: _var class has a normal Test_st*& operator that returns the internal pointer (actually, a reference to it, which is assigned to t_out).=20 Then, the server implementation code does something like: t_out =3D new Test::Test_st(); ... That is, it is accessing (through a reference) to the *internal* pointer of a _var variable (st), and it is modifying without telling the actual _var variable. So the *previous* value of the internal _var variable pointer now leaks. It is now clear enough? With _out type, you force a conversion from _var to _out, in which the previous internal pointer of the _var variable is (correctly) deallocated before the call enters in the actul implementation. Hope this helps. diego. |=20 | --=20 | .--=3D ULLA! =3D---------------------. `We are not here to give us= ers what | \ http://cactus.rulez.org \ they want' -- RMS, at GUADEC = 2001 | `---=3D ca...@ca... =3D---' | find / -user `grep ^you: /etc/passwd|cut -d: -f3` -a -name base -exec c= hown us.us {} \; |=20 --=20 Diego Sevilla Ruiz http://ditec.um.es/~dsevilla dse...@um... \ /\ Dpto. Ingenier=EDa y Tecnolog=EDa de Computadores http://ditec.um.es ) = ( ') Visiting Extreme! Computing Lab http://extreme.indiana.edu ( / ) Indiana University, Bloomington http://www.iub.edu \(__)| |