www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Strange memory corruption / codegen bug?

reply TheGag96 <thegag96 gmail.com> writes:
I was porting my Evolutionary Computing homework written in 
Python over to D, and I've come across this bug I cannot for the 
life of me figure out.

https://gitlab.com/TheGag96/evo-pacman/blob/master/source/pacman/tree.d#L139

I don't think I could cut this down to a smaller reproducible 
scenario due to how bizarre and specific this problem is, so I 
apologize in advance if this is hard to follow.

Basically, imagine that I have a binary tree class where, due to 
how my program is set up, each node will have either children on 
both the left and right side or no children at all (the latter 
represented by a value of null for Tree's left and right member). 
I have a member function called "dup" -- marked const, mind you 
-- that just returns a deep copy of the tree and SHOULDN'T make 
any changes to the calling object.

I call this function a couple different places and it appears to 
function okay, but at the spot I linked, if I call .dup here, it 
will corrupt one of the tree's nodes and put something in its 
left member for no apparent reason. This oddly doesn't happen on 
every Tree calling this function. This could definitely be some 
stupid mistake on my part, but the fact that calling a 
const-marked function changes the state of the calling object 
makes me think something else is afoot here...

I would greatly appreciate anyone who would be willing to take a 
look at this. This bug is driving me absolutely nuts.
Dec 11 2016
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 12/12/2016 12:15 AM, TheGag96 wrote:
 I was porting my Evolutionary Computing homework written in Python over
 to D, and I've come across this bug I cannot for the life of me figure out.

 https://gitlab.com/TheGag96/evo-pacman/blob/master/source/pacman/tree.d#L139
Not public, please pastebin.
 I don't think I could cut this down to a smaller reproducible scenario
 due to how bizarre and specific this problem is, so I apologize in
 advance if this is hard to follow.

 Basically, imagine that I have a binary tree class where, due to how my
 program is set up, each node will have either children on both the left
 and right side or no children at all (the latter represented by a value
 of null for Tree's left and right member). I have a member function
 called "dup" -- marked const, mind you -- that just returns a deep copy
 of the tree and SHOULDN'T make any changes to the calling object.

 I call this function a couple different places and it appears to
 function okay, but at the spot I linked, if I call .dup here, it will
 corrupt one of the tree's nodes and put something in its left member for
 no apparent reason. This oddly doesn't happen on every Tree calling this
 function. This could definitely be some stupid mistake on my part, but
 the fact that calling a const-marked function changes the state of the
 calling object makes me think something else is afoot here...

 I would greatly appreciate anyone who would be willing to take a look at
 this. This bug is driving me absolutely nuts.
Dec 11 2016
parent reply TheGag96 <thegag96 gmail.com> writes:
On Sunday, 11 December 2016 at 11:17:50 UTC, rikki cattermole 
wrote:
 Not public, please pastebin.
https://github.com/TheGag96/evo-pacman/blob/master/source/pacman/tree.d#L135 I just put it on GitHub. No idea why the repo wasn't public even after I set it to be public...
Dec 11 2016
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
On 12/12/2016 12:43 AM, TheGag96 wrote:
 On Sunday, 11 December 2016 at 11:17:50 UTC, rikki cattermole wrote:
 Not public, please pastebin.
https://github.com/TheGag96/evo-pacman/blob/master/source/pacman/tree.d#L135 I just put it on GitHub. No idea why the repo wasn't public even after I set it to be public...
Can you please create a function that will cause this error to occur? E.g. generate the source code from the tree. That way we can test against it.
Dec 11 2016
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
On 12/11/2016 12:43 PM, TheGag96 wrote:
 On Sunday, 11 December 2016 at 11:17:50 UTC, rikki cattermole wrote:
 Not public, please pastebin.
https://github.com/TheGag96/evo-pacman/blob/master/source/pacman/tree.d#L135 I just put it on GitHub. No idea why the repo wasn't public even after I set it to be public...
Try putting an `assert(childCrossPoint !is otherCrossPoint);` before the assignment. If it fails, the variables refer to the same node. That would explain how otherCrossPoint.left gets set. Also, what compiler are you using, what version of it, and on which platform?
Dec 11 2016
next sibling parent safety0ff <safety0ff.dev gmail.com> writes:
On Sunday, 11 December 2016 at 11:58:39 UTC, ag0aep6g wrote:
 Try putting an `assert(childCrossPoint !is otherCrossPoint);` 
 before the assignment. If it fails, the variables refer to the 
 same node. That would explain how otherCrossPoint.left gets set.
Furthermore, I think he is calling breed on a Tree with itself. i.e. assert(other !is this) would be a more reliable test since it won't be subject to randomness.
Dec 11 2016
prev sibling parent TheGag96 <thegag96 gmail.com> writes:
On Sunday, 11 December 2016 at 11:58:39 UTC, ag0aep6g wrote:
 Try putting an `assert(childCrossPoint !is otherCrossPoint);` 
 before the assignment. If it fails, the variables refer to the 
 same node. That would explain how otherCrossPoint.left gets set.
Ahh... This led me to it. I was about to say "That wouldn't be possible, childCrossPoint is part of a clone of the original caller!" But then I realized I did "this.getNodeList" towards the beginning instead of "child.getNodeList". I feel very silly right now, haha. Thanks for the help and your patience, guys.
Dec 11 2016