Re: C++ mapping of OUT variable-length structures



Hi!

On Wed, Apr 24, 2002 at 09:31:55PM +0200, ERDI Gergo wrote:
| On Wed, 24 Apr 2002, Diego Sevilla Ruiz wrote:
| 
| > | So this is useful when you pass in (on the caller side) a non-empty
| > | structure, right?
| > 
| > 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...)
| 
| OK so let's talk about actual code here.
| 
| Suppose I have the following on the client side:
| 
| 	Test::Test_st *strct;
| 	master_ptr->foo (strct);
| 	// Do stuff on strct
| 	delete strct;

OK.

| 
| The signature of foo is, according to this _out convention:
| 
| 	void foo (Test::Test_st_out struct_out);
| 
| So in the above example, when master_ptr->foo returns, struct_out points
| to a valid structure, right?
| 
| So, what happens when instead, the following is done:
| 
| 	Test::Test_st *strct = new Test::Test_st;
| 	// Fill strct
| 	// Use it as an IN parameter
| 	other_ptr->other_method (*strct);
| 		
| 	master_ptr->foo (strct);
| 
| 	delete strct;
| 

So you are leaking memory here. That of the previous "new" allocated
struct. 

The correct code is to either 

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 could
| use vanilla Test::Test_st*&'s as the OUT argument type and do the same.
| 

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 = 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). 

Then, the server implementation code does something like:

t_out = 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.

| 
| -- 
|    .--= ULLA! =---------------------.   `We are not here to give users what
|    \     http://cactus.rulez.org     \   they want'  -- RMS, at GUADEC 2001
|     `---= cactus@cactus.rulez.org =---'
| find / -user `grep ^you: /etc/passwd|cut -d: -f3` -a -name base -exec chown us.us {} \;
| 

-- 
Diego Sevilla Ruiz  http://ditec.um.es/~dsevilla  dsevilla@um.es  \    /\
Dpto. Ingeniería y Tecnología de Computadores http://ditec.um.es   )  ( ')
Visiting Extreme! Computing Lab       http://extreme.indiana.edu  (  /  )
Indiana University, Bloomington               http://www.iub.edu   \(__)|



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]