I have "invented" a linked-list technique in vb6 by placing a pointer inside the object:
Class FooBar:
Public ptr As FooBar
Now I just hold a pointer to the head of the list, inside Head.ptr points to the next object, Head.ptr.ptr points to the next object, etc.
When I want to destroy the list I just use Set Head = Nothing, this result in clearing Head.ptr, which in turn triggers clearing Head.ptr.ptr etc, resulting in an empty list (I actually checked it by placing a break-point in the Class_Terminate event).
This works nice and neat, until I have like 10,000 objects in the list. Now the line Set Head = Nothing results in "Out of stack memory" error, after which an IDE crash.
Turns out, vb6 is clearing the object recursively (it happens even if I don't have the Class_Terminate event).
So I thought I should destroy the list "manually", with some sort of loop. but I couldn't figure out a way to do so, as using a pointer in the loop and setting it to Nothing does... nothing since it AddRef to the object!
What should I do???
I Finally worked out a way to manually destroy the list.
A somewhat tricky but working solution.
I first add a small method to the class that clears the internal pointer without removing the object.
Class FooBar:
Public ptr As FooBar
Public Function SafeRemove() As FooBar
Set SafeRemove = ptr
Set ptr = Nothing
End Function
In a module:
Sub ClearList()
While Head Is Nothing = False
Set Head = Head.SafeRemove
Wend
End Sub
I can understand why you get a stack overflow. You are implicitly calling the Release() method of the IUnknown interface, which them calls an internal VB destroy method, which clears down all internal state, including the variable which points to the next item, which then calls Release(), etc., etc.
To get around the stack overflow problem, you would be better off implementing a doubly linked list, and always saving a pointer to the end of the list. But then you would now have the problem of circular references, and nothing would clear down unless you had a specific disposal method.
You might as well use the VBA.Collection object, which I have been told (in the book Hardcore Visual Basic is a doubly linked list internally).
Related
Recently I wrote a little application using Ruby and Qt. It was my first non-trivial project with qtruby. After some time I managed to translate C++ references and tutorials into working Ruby code, and got the hang of it.
Only when implementing my own drag and drop functionality in QTreeView widgets, I got really stuck. I could isolate the problem to the Qt::AbstractItemModel::mimeData method. After eliminating some other mistakes, I ended up with the following code which somehow caused the application to crash as soon as a drag action occured.
class TreeModel < Qt::AbstractItemModel
def mimeData(indexlist)
encodedData = Qt::ByteArray.new("")
stream = Qt::DataStream.new(encodedData, Qt::IODevice::WriteOnly)
indexlist.each do |index|
if index.column == 0
if index.isValid
stream << index.item.mime_data.to_json
end
end
end
mimeData = Qt::MimeData.new
mimeData.setData("application/x-tegi.json", encodedData)
mimeData
end
end
The crash appeared non-deterministic, a few times the code just worked. The error dump and backtrace did not give me a hint, only that the crash happened inside QApplication::exec.
What is the issue and how can it be fixed?
The C++ prototype for mimeData is :
QMimeData * QAbstractItemModel::mimeData
( const QModelIndexList & indexes ) const [virtual]
The method returns a pointer to a QMimeData object. My implementation of mimeData was returning a pointer to a local variable. Thus the non-deterministic crashes.
Once found, fixing the issue was easy. An instance variable would stay alive and keep its value until the next call of mimeData:
#mimeData = Qt::MimeData.new
#mimeData.setData("application/x-tegi.json", encodedData)
#mimeData
end
Another possibility is to call super and leave the construction and deconstruction to the superclass. This also inherits the default mime data ("application/x-qabstractitemmodeldatalist"):
mimeData = super
mimeData.setData("application/x-tegi.json", encodedData)
mimeData
end
After having found the issue, it appears trivial to me. Nevertheless I would like to share it, because I wasted too much time with it. The qtruby documentation warns about pointer arguments and mentions some unsupported functions returning uchar pointers, but no word about functions returning pointers to Qt objects. Being lulled by qtruby seamlessly wrapping data types to and fro, I looked so many times over that little asterisk without spotting it.
Does creating intermediate variables cause the garbage collector to do more work?
That is, is there any difference between:
output = :asdf.to_s.upcase
and
str = :asdf.to_s
output = str.upcase
? (Assume str is never referenced again.)
It would be a trivial amount of extra work when marking objects still referenced, assuming both str and output were still in scope (i.e. the binding where they exist was still active) when the GC mark phase began. Both variables would start a mark on the same string. I don't know, but suspect that when marking objects as still viable, if Ruby comes across an item already marked, it will probably stop recursing and go to its next item at the same level. In this case the String is a single object without child objects to mark further, so it's one quick call to rb_gc_mark repeated for each reference to the String - one case where it is marked, and another case where Ruby notes it has already been marked and stops recursing.
If neither variable were in any active binding when GC mark phase began, it is no extra work, the String referenced would not get marked (no work) and the sweep phase would delete it just once (same work no matter how many references were active before).
Base on this artical, http://www.drdobbs.com/cpp/when-is-it-safe-to-move-an-object-instea/240156579#disqus_thread
Following code will NOT call the move constructor:
void func()
{
Thing t;
work_on(t);
// never using t variable again ...
}
Following code will call the move constructor:
work_on(Thing());
The reason is for the first code snippet, the constructor may save the constructing object address, and use it later.
My question is:
But for the second code snippet, the temp object still are alive before work_on finished base on the C++ standard, so the author can also save the address of the constructing object, and use it inside work_on function.
So base on the same reason, it also shouldn't call move constructor, doesn't this make sense?
void func()
{
Thing t;
work_on(t); // <--- POINT 1
work_on(move(t)); // <--- POINT 2
work_on(Thing()); // <--- POINT 3
}
The expression t at POINT 1 is an lvalue.
The expression move(t) at POINT 2 is an xvalue.
The expression Thing() at POINT 3 is a prvalue.
Based on this value category of an expression, a best viable function is chosen from the overloaded set.
Suppose the two available functions were:
work_on(const Thing&); // lvalue reference version
work_on(Thing&&); // rvalue reference version
An lvalue will select the lvalue reference version, and will never bind to the rvalue reference version.
An xvalue or prvalue (collectively called rvalues) will viably bind to either, but will select the rvalue reference version as the better match if available.
Inside the implementation of the two versions of work_on, the parameters are largely the same. The purpose of this is that the rvalue reference version can assume that the argument is theirs to modify or move. So it may call the move constructor on its argument - whereas the lvalue reference version should not.
So suppose we had some vector<Thing> V that work_on should add their parameter to:
void work_on(Thing&& t)
{
V.push_back(move(t));
}
void work_on(const Thing& t)
{
V.push_back(t);
}
std::vector::push_back is overloaded in a similar fashion to work_on, and a similar overload resolution takes place. Inside the two different implementations of push_back, the rvalue reference version will call the move constructor to push the value onto its array, possibly destroying t. The lvalue reference version will call the copy constructor, leaving t intact.
The main purpose of this language mechanic is simply to keep track of variables (lvalues), intentionally marked expiring values (xvalues) and temporaries (prvalues) - so we know when we can safely reuse their resources (move them) and when we can copy them.
You got all your reasons wrong. There's nothing about "saving addresses". (Anyone can write any manner of horribly broken code by randomly storing addresses. That's not an argument.)
The simple reason is that in the first snippet, t continues living and can be used, so you can't move from it:
Thing t;
work_on(t);
t.x = 12;
foo(t);
In the second snippet, though, the temporary value Thing() only lives on that one line, till the end of the full-expression, so nobody can possibly refer to that value after the end of the statement. Thus it's perfectly safe to move from (i.e. mutate) the object.
We have all read about or heard about the stack class, but many of us have probably never found a reason to use the LIFO object. I am curious to hear of real world solutions that used this object and why.
http://msdn.microsoft.com/en-us/library/system.collections.stack.aspx
I recently saw an example where a programmer used a stack to keep track of his current position while traversing a hierarchical data source. As he moved down the hierarchy, he pushed his position identifier on to the stack and as he moved back up he popped items off the stack. I thought this was a very efficent way to keep track of his current position in a mamoth hierarchy. I had never seen this before.
Anyone else have any examples?
I've used them to keep track of Undo and Redo actions.
I use an interface something like this:
interface ICommand
{
void Execute();
void Undo();
string Description { get; }
}
Undo and Redo are both of type Stack<ICommand>. Then I create a concrete class for a given action. In the class's constructor, I pass in any information I'd need to hold on to. Execute does the action initially, and also redoes it; Undo undoes it, obviously. It works like this:
Undo an action: Pop the Undo stack and add to the Redo stack.
Redo an undone action: Pop the Redo stack and add to the Undo stack again.
Perform a new action: Add to the Undo stack and clear the Redo stack (since the state is no longer consistent).
I found that you have to take care that you're really undoing what was done. For instance, say you have a UI with two listboxes, and each has five items in it. Your action might be to click a button to move everything on the left list to the right list (so it now has ten, and the left list has zero).
The undo action is not to move everything back; the undo action is to move back only the five you actually moved, and leave the others.
Stacks are used whenever a stored procedure / sub-routine is called to store local variables and return address.
Stacks are used for expression evaluation (eg in a calculator, or your compiler), first the expression is converted to RPN then a simple stack machine is used to evaluate. This works as follows, when you see an operand push it on the stack. When you see an operator pop operands and evaluate.
example
5 6 + 3 *
steps-
see 5 push 5
see 6 push 6
see + pop 2 times and apply + get 11 push 11
see 3 push 3
see * pop 2 times and apply get 33 push 33
result is on the top of the stack.
If you have a recursive algorithm, you can typically rewrite them using a stack. (since recursive algorithms implicitly already use a stack)
You can validate string inputs that require balanced tokens. Think LISP:
(+ (- 3 2) (+ (+ 4 5) 11))
When you hit an opening paren:
stack.Push("(")
Then when you hit a closing paren:
stack.Pop()
If there are any tokens left in your stack when you're done, it's not balanced.
You can get fancier and validate proper nesting in inputs like HTML. In a highly-contrived example:
//see opening body
stack.Push("body")
//see opening div
stack.Push("div")
//see opening p
stack.Push("p")
///see closing div
if(!stack.Pop().Equal("div")){
//not balanced
}
I've used stacks for image processing, where the "processing language" must be specified in a URL. A stack-based form lets you represent a tree of operations in an easy-to-parse, easy-to-think-about form.
See:
http://www.hackification.com/2008/10/29/stack-based-processing-part-1/
and
http://www.hackification.com/2008/10/29/stack-based-processing-part-2/
In one real-life use, a postscript generator class has a "current_font" state, used as the font for any operations which draw text. Sometimes a function needs to set the font temporarily, but then have it go back to the way it was. We could just use a temporary variable to save and restore the font:
def draw_body
old_font = ps.get_font
ps.set_font('Helvetica 10')
draw_top_section
draw_bottom_section
ps.set_font(old_font)
end
But by the third time you've done that you'll want to stop repeating yourself. So let's let the ps object save and restore the font for us:
class PS
def save_font
old_font = get_font
end
def restore_font
set_font(old_font)
end
end
Now the caller becomes:
def draw_body
ps.save_font
ps.set_font('Helvetica 10')
draw_top_section
draw_bottom_section
ps.restore_font
end
That works fine, until we use the same pattern inside one of the subroutines called by draw_page:
def draw_top_section
ps.save_font
ps.set_font('Helvetica-bold 14')
# draw the title
ps.restore_font
# draw the paragraph
end
When draw_top_section calls "save_font", it clobbers the font that was saved by draw_page. It's time to use a stack:
def PS
def push_font
font_stack.push(get_font)
end
def pop_font
set_font(font_stack.pop)
end
end
And in the callers:
def draw_top_section
ps.push_font
ps.set_font('Helvetica-bold 14')
# draw the title
ps.pop_font
# draw the body
end
There are further refinements possible, such as having the PS class automatically save and restore the font, but it's not necessary to go into those to see the value of a stack.
I find stacks quite useful in multithreaded aplications to keep track of statuses in an inverse-time fashion...
Every thread puts a status message in a synchronized shared stack and you have kind of a "breadcrumb" of what has happened.
Not quite .NET but... it's my oppinion =)
Here's an implementation of a deep compare where a Stack is used to keep track of the path to the current object being compared.
C# implementation of deep/recursive object comparison in .net 3.5
I've also used it in similar types of code working with generating xpath statements for particular xml nodes.
To provide a specific example to illuminate what other people are commenting on: to implement a Z-machine interpreter three different stacks should be used. A call stack, and a couple different kinds of object stacks. (The specific requirements can be found here.) Note that, like all of these examples, while using a stack isn't strictly required, it is the obvious choice.
The call stack keeps track of recursive calls to subroutines, while the object stack is used to keep track of internal items.
In a computer graphics class (not .NET) we used a Stack to keep track of objects that were drawn on the screen. This allowed all the objects to be redrawn on the screen for each refresh as well as keeping track of the order or "z-layer" of each object, so when they moved they could overlap other objects.
I am working my way through Ferret (Ruby port of Lucene) code to solve
a bug. Ferret code is mainly a C extension to Ruby. I am running into
some issues with the garbage collector. I managed to fix it, but I
don't completely understand my fix =) I am hoping someone with deeper
knowledge of Ruby and C extension (this is my 3rd day with Ruby) can
elaborate. Thanks.
Here is the situation:
Some where in Ferret C code, I am returning a "Token" to Ruby land.
The code looks like
static VALUE get_token (...)
{
...
RToken *token = ALLOC(RToken);
token->text = rb_str_new2("some text");
return Data_Wrap_Struct(..., &frt_token_mark, &frt_token_free, token);
}
frt_token_mark calls rb_gc_mark(token->text) and frt_token_free
just frees the token with free(token)
In Ruby, this code correlates to the following:
token = #input.next
Basically, #input is set to some object, calling the next method on it
triggers the get_token C call, which returns a token object.
In Ruby land, I then do something like w = token.text.scan('\w+')
When I run this code inside a while 1 loop (to isolate my problem), at
some point (roughly when my ruby process mem footprint goes to 256MB,
probably some GC threshold), Ruby dies with errors like
scan method called on terminated object
Or just core dumps. My guess was that token.text was garbage collected.
I don't know enough about Ruby C extension to know what happens with
Data_Wrap_Struct returned objects. Seems to me the assignment in Ruby
land, token =, should create a reference to it.
My "work-around"/"fix" is to create a Ruby instance variable in the
object referred to by #input, and stores the token text in there, to
get an extra reference to it. So the C code looks like
RToken *token = ALLOC(RToken);
token->text = rb_str_new2(tk->text);
/* added code: prevent garbage collection */
rb_ivar_set(input, id_curtoken, token->text);
return Data_Wrap_Struct(cToken, &frt_token_mark, &frt_token_free, token);
So now I've created a "curtoken" in the input instance variable, and
saved a copy of the text there... I've taken care to remove/delete
this reference in the free callback of the class for #input.
With this code, it works in that I no longer get the terminated object
error.
The fix seems to make sense to me -- it keeps an extra ref in curtoken
to the token.text string so an instance of token.text won't be removed
until the next time #input.next is called (at which time a different
token.text replaces the old value in curtoken).
My question is: why did it not work before? Shouldn't
Data_Wrap_Structure return an object that, when assigned in Ruby land,
has a valid reference and not be removed by Ruby?
Thanks.
When the Ruby garbage collector is invoked, it has a mark phase and a sweep phase. The mark phase marks all objects in the system by marking:
all objects referenced by a ruby stack frame (e.g. local variables)
all globally accessible objects (e.g. referred to by a constant or global variable) and their children/referents, and
all objects referred to by a reference on the stack, as well as those objects' children/referents.
as well as a number of other objects that are not important to this discussion. The sweep phase then destroys any objects that are not accessible (i.e. those that were not marked).
Data_Wrap_Struct returns a reference to an object. As long as that reference is available to ruby code (e.g. stored in a local variable) or is on the stack (referred to by a local C variable), the object should not be swept.
It's looks like from what you've posted that token->text is getting garbage collected. But why is it getting collected? It must not be getting marked. Is the Token object itself getting marked? If it is, then token->text should be getting marked. Try setting a breakpoint or printing a message in the token's mark function to see.
If the token is not getting marked, then the next step is to figure out why. If it is getting marked, then the next step is to figure out why the string returned by the text() method is getting swept (maybe it's not the same object that is getting marked).
Also, are you sure that it is the token's text member that is causing the exception? Looking at:
http://github.com/dbalmain/ferret/blob/master/ruby/ext/r_analysis.c
I see that the token and the token stream both have text() methods. The TokenStream struct doesn't hold a reference to its text object (it can't, as it's a C struct with no knowledge of ruby). Thus, the Ruby object wrapping the C struct needs to hold the reference (and this is being done with rb_ivar_set).
The RToken struct shouldn't need to do this, because it marks its text member in its mark function.
One more thing: you may be able to reproduce this bug by calling GC.start explicitly in your loop rather than having to allocate so many objects that the garbage collector kicks in. This won't fix the problem but might make diagnosis simpler.
perhaps mark as volatile:
http://www.justskins.com/forums/chasing-a-garbage-collection-bug-98766.html
maybe your compile is keeping its reference in a registry instead of the stack...there is some way mentioned I think in README.EXT to force an object to never be GC'ed, but...the question still remains as to why it's being collected early...