www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Help to find crash in simple stack type?

reply "Gary Willoughby" <dev nomad.so> writes:
I've created a simple stack type using calloc/free which seems to 
work nicely. Then instead of using C functions i've tried to 
implement the same type using the GC. However i'm experiencing a 
crash. I've been staring at this snippet for hours now any help 
would be appreciated. This is a simplified snippet showing the 
crash:

import std.stdio;
import core.memory;

class Stack(T)
{
	private T* _data;
	private T* _pointer;
	private immutable size_t _minimumSize;
	private size_t _size;
	private size_t _count;

	public this()
	{
		this._minimumSize = 32_000;
		this._size = this._minimumSize;
		this._data = cast(T*)GC.calloc(this._size, GC.BlkAttr.NO_MOVE);
		this._pointer = this._data;
		this._pointer--;
	}

	public void push(T value)
	{
		this._pointer++;

		if ((this._size / T.sizeof) < (this._count + 1))
		{
			this._size *= 2;
			writefln("realloc to %s bytes", this._size);
			this._data = cast(T*)GC.realloc(this._data, this._size, 
GC.BlkAttr.NO_MOVE);
			this._pointer = (this._data + this._count);
		}

		this._count++;
		*this._pointer = value;
	}
}

unittest
{
	auto stack = new Stack!(int);

	for (int x = 1; x <= 300_000 ; x++)
	{
		stack.push(x);
	}
}

It seems to crash when the loop iteration is at about 260,000 and 
i've no idea why. I'm using Ubuntu 64bit latest DMD.
Jul 12 2014
parent reply "anonymous" <anonymous example.com> writes:
No explanation or solution, but a reduction:

import core.memory;
void main()
{
      alias T = ubyte;

      enum size1 = 2_049; /* > 2_048 = 2^^11 */
      enum size2 = 1_048_577; /* > 1_048_576 = 2^^20 */

      T* _data;
      _data = cast(T*)GC.calloc(size1, GC.BlkAttr.NO_MOVE);
      _data = cast(T*)GC.realloc(_data, size2, GC.BlkAttr.NO_MOVE);

      T* _pointer = _data;
      foreach(i; 0 .. size2)
      {
          *_pointer = 0; /* segfault at i = 1_048_576 */
          _pointer++;
      }
}
Jul 12 2014
parent reply Rainer Schuetze <r.sagitario gmx.de> writes:
On 12.07.2014 16:24, anonymous wrote:
 No explanation or solution, but a reduction:

 import core.memory;
 void main()
 {
       alias T = ubyte;

       enum size1 = 2_049; /* > 2_048 = 2^^11 */
       enum size2 = 1_048_577; /* > 1_048_576 = 2^^20 */

       T* _data;
       _data = cast(T*)GC.calloc(size1, GC.BlkAttr.NO_MOVE);
       _data = cast(T*)GC.realloc(_data, size2, GC.BlkAttr.NO_MOVE);

       T* _pointer = _data;
       foreach(i; 0 .. size2)
       {
           *_pointer = 0; /* segfault at i = 1_048_576 */
           _pointer++;
       }
 }
Thanks for the reduction. GC.realloc seems broken for reallocations to sizes larger than the current GC pool. Please file a bug report.
Jul 12 2014
parent reply Rainer Schuetze <r.sagitario gmx.de> writes:
On 12.07.2014 19:05, Rainer Schuetze wrote:
 Thanks for the reduction. GC.realloc seems broken for reallocations to
 sizes larger than the current GC pool.

 Please file a bug report.
Actually done that myself: https://issues.dlang.org/show_bug.cgi?id=13111
Jul 12 2014
parent "Gary Willoughby" <dev nomad.so> writes:
On Saturday, 12 July 2014 at 17:11:00 UTC, Rainer Schuetze wrote:
 On 12.07.2014 19:05, Rainer Schuetze wrote:
 Thanks for the reduction. GC.realloc seems broken for 
 reallocations to
 sizes larger than the current GC pool.

 Please file a bug report.
Actually done that myself: https://issues.dlang.org/show_bug.cgi?id=13111
Thanks a lot guys!
Jul 13 2014