On Fri, 12 Nov 2010 06:34:02 -0500, spir <denis.s...@gmail.com> wrote:
On Thu, 11 Nov 2010 23:45:39 +0100
Pelle Månsson <pelle.mans...@gmail.com> wrote:
On 11/11/2010 10:15 PM, spir wrote:
> Well, since the pattern is OK _after_ call to Tuple's constructor
(which does nothing more than recording its sub-patterns, see below)
and only gets wrong when qutting this(), I fail to see how Tuple could
be cause of anything. Also, the corruption is visible _before_ calling
match() (which here delegates to Tuple's check()).
>
> I understand your note about returning an object actually allocated
on the stack -- but here there are only implicitely referenced objects
(class instances). This would mean that D creates the 2 sub-patterns on
the stack? But why those objects, precisely? (Also note that they are
of different classes: one is here a "String", the other a
"ZeroOrMore"). They are stored in an array.
>
> What's troubling is that the array elements, meaning the supposed
subpattern addresses, have changed. Maybe the patterns themselves are
still ok, but the array data only are corrupted?
> Oh, I may try to cast to String the memory area pointed inside
this()....... Does not seem to work: I recorded the pointer read in
this() (as String*) into a global; then in the test func:
> writeln("p: ",p); // ok, same address as in this()
> writeln(cast(String)(*p)); // segfault!
>
> Anyway, just in case my reasoning is wrong, here is the whole Tuple
class:
>
> ====================================================
> class Tuple : Pattern {
> /** pattern type for tuple of given patterns */
> static string typename = "Tuple";
> Pattern[] patterns;
> this (Pattern[] patterns...) {
> this.patterns = patterns;
You need to dup that. Arguments are passed on the stack.
Sorry, but I don't understand your hint. Where is the dup-ed array
supposed to be allocated? Isn't the assignment supposed to copy it to
the field, anyway? How else could one store an array to a field? And how
are contained referenced objects supposed to stop vanishing thank to dup?
(I tried, anyway, but the did not stop segfault.)
Pelle, I spent all this time helping him, and you swoop in with the answer
:)
Yes, he is right, you need to dup the patterns argument. It is something
I very recently discovered.
Here is what happens:
void foo(int[] arg...) {}
foo(1,2,3);
What the compiler does is push 1, 2, and 3 onto the stack, then passes in
a dynamic array reference to that stack data. It does this because heap
allocations are much more expensive than stack allocations. When you just
"save" the data, it is no longer valid. The reason the code all works
within the List constructor is because that is the stack frame where the
array is pushed onto the stack.
Note, you can do foo([1,2,3]), and you will be wasting time duping, but I
have found a solution to that, overloading:
void foo(int[] arg) {}
If you pass in an array, then the second overload is used, if you pass in
individual arguments the first overload is used.
Essentially, if you change your line above to:
this.patterns = patterns.dup;
All is well, you should be good.
-Steve