bug in use of shallow copy

Frank Fock Frank.Fock____t-online.de
Wed Dec 4 20:10:05 CET 2002


Hi Dan,

It works as designed (may be the design is a bit clumsy ;-).
It is documented in the method documentation of get_rows
(there is a typo in it: replace "constructor" by "destructor"):
http://www.agentpp.com/doc3.x/classMibTable.html#a39

in particular:
Note:
Don't use this method for tables where rows are deleted, because you 
only get references, that then may point to nowhere.
Call List::clear() method before its destructor to avoid deletion of the 
rows of this table.

So in your code:
 >   List<MibTableRow>* tableRows = tablePtr->get_rows( );
 >   ListCursor<MibTableRow>  tableRowsCursor;
 >   MibTableRow* rowPtr = 0;
 >   for(tableRowsCursor.init(tableRows);
 >       rowPtr = tableRowsCursor.get();
 >       tableRowsCursor.next())
 >   {
 >      // check if rowPtr is the row we are looking for and if so, break
 > out of the for loop
 >   }
table.clear();
 >   delete tableRows;
 >   return rowPtr;

Best regards,
Frank

Dan Perl wrote:
> I found something that seems to me to be a bug, unless I misunderstand 
> the use of some classes.  Note: we are using version 3.5.1 (according to 
> the CHANGES file in the top directory).
> 
>  
> 
> MibTable::getRows( ) makes a shallow copy of the rows in MibTable.  It 
> creates a ?new List<MibTableRow>? and it adds one-by-one one ?MibTableRow *? to the list, for every row 
> in the table.  However, the destructor ~List( ) invokes List::clearAll( 
> ) which in turn deletes also the items in the list (the pointers added 
> to list).  Here is the code from ~List( ):
> 
>             void clearAll() {
> 
>                         ListItem<T>* tmp = head;
> 
>                         ListItem<T>* del;
> 
>                         while (tmp) {
> 
>                                     delete tmp->item;
> 
>                                     del = tmp;
> 
>                                     tmp = tmp->next;
> 
>                                     delete del;
> 
>                         }
> 
>                         head = 0;
> 
>                         tail = 0;
> 
>             }
> 
> This is causing a segmentation fault in my code.  I commented out the 
> ?delete tmp->item? line, I ran my code through Purify, and my problem is solved, and 
> there are no memory leaks.
> 
>  
> 
> I?m not sure whether there are some other uses of List where the items 
> should be indeed deleted in thedestructor, but it looks to me like this 
> is a clear problem for my case.  Am I supposed to access the rows of a 
> table using some other API methods?  I need to traverse the rows, 
> searching for a row with a specific value in one of the columns.  Here 
> is what my code looks like:
> 
>   List<MibTableRow>* tableRows = tablePtr->get_rows( );
> 
>   ListCursor<MibTableRow>  tableRowsCursor;
> 
>   MibTableRow* rowPtr = 0;
> 
>   for(tableRowsCursor.init(tableRows);
> 
>       rowPtr = tableRowsCursor.get();
> 
>       tableRowsCursor.next())
> 
>   {
> 
>      // check if rowPtr is the row we are looking for and if so, break 
> out of the for loop
> 
>   }
> 
>   delete tableRows;
> 
>   return rowPtr;
> 
>  
> 
> Note: I have to delete tableRows, or else it is a memory leak.  However, 
> I do need the rowPtr after that as a pointer INSIDE the actual table.  
> So I do need MibTable::getRows to make a shallow copy but it should not 
> destroy the copied items.  Of course, that?s so unless I am misusing the 
> API and there is another way to do what I need.
> 
>  
> 
> I changed the agent++ code for our use, but I would appreciate a reply 
> either with another way to use the API or with a confirmation that this 
> is a bug which will be fixed in a later release.
> 
>  
> 
> Thanks,
> 
>  
> 
> Dan Perl
> 
> Taral Networks
> 
> Ottawa, Canada
> 
>  
> 







More information about the AGENTPP mailing list