Heap corruption in reading struct fields in ctor

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Dec 19 18:39:42 PST 2012


Better yet, here's a slightly different version of the code that
outright segfaults:


---- CODE ----

import std.range;
import std.stdio;

struct TransientStringArray
{
	dstring[] src;
	dchar[256] buf;

	this(dstring[] _src) {
		src = _src;
	}

	@property auto front() {
		assert(src[0].length <= buf.length);
		foreach (i, ch; src[0]) {
			buf[i] = ch;
		}
		return buf[0 .. src[0].length];
	}
}

auto joiner(RoR)(RoR r)
{
    static struct Result
    {
    private:
        RoR _items;
        ElementType!RoR _current;
    public:
        this(RoR r)
        {
            _items = r;
            _current = _items.front;	// This produces heap corruption
            //_current = r.front;		// This doesn't???!!!
        }
        @property auto ref front()
        {
            return _current.front;
        }
    }
    return Result(r);
}

auto makeTransientString() {
	auto arr = [ "ab"d, "cd", "ef" ];
	auto tsa = TransientStringArray(arr);
	//auto tsa = TransientStringArray([ "ab", "cd", "ef" ]);
	return joiner(tsa);
}

void func4(T)(T t) {
	writeln("func4:front = ", t.front);
}

void func3(T)(T t) {
	writeln("front = ", t.front);
	// Segfaults here
	func4(t);
}

void func2(R)(R src) {
	func3(src);
}

void func1(S)(S src) {
	func2(src);
}

void main() {
	// This produces a heap corruption
	{
		auto result = makeTransientString();
		func1(result);
	}

	// For some weird reason, this doesn't (or at least, it doesn't show
	// up)
	{
		auto result = makeTransientString();
		func2(result);
	}
}


More information about the Digitalmars-d mailing list