www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Strange seg fault

reply "gedaiu" <szabobogdan yahoo.com> writes:
Hi,

Can anyone help me why this code goes wrong? I get exit code 139 
with DMD 2.063


import std.stdio;



struct Test {
	string val = "";
	string[] key;
	
	/**
	 * operator "=" overload
	 */
	Test opAssign(string val){
		this.val = val;
		
		string[1] t;
		t = val;
		
		key ~= t;
		
		return this;
	}
	
	Test opAssign(Test val){
		this.val = val.val;
		
		key ~= val.key;
		
		return this;
	}
	
	void append(Test t) {
		val ~= t.val;
		key ~= t.key;
	};
}

void main() {
	
	Test val;
	val = "test";
	
	Test[string] data;
	Test v;
	v = "asd";
	data["test"] = v;
	
	writeln(v);
	writeln(data["test"]);
	
	data["test"].append(val);
	
	
	writeln(data["test"].key);
	writeln("done");
}

Thanks,
Bogdan
Jun 12 2013
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
I think you've hit bug city in the associative array 
implementation. The "this" in there doesn't seem to point at 
anything meaningful. This is probably worthy of a bug report.

A potential workaround is to store pointers to your structs in 
the associative array, that way you can set them up ahead of 
time, then just do data["test"] = ptr; instead.
Jun 12 2013
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/12/2013 01:12 PM, gedaiu wrote:

 Hi,

 Can anyone help me why this code goes wrong? I get exit code 139 with
 DMD 2.063


 import std.stdio;



 struct Test {
      string val = "";
      string[] key;

      /**
       * operator "=" overload
       */
      Test opAssign(string val){
          this.val = val;

          string[1] t;
          t = val;

          key ~= t;
Instead of the last three lines: key ~= val; However, if you really wanted a 1-element fixed-length array then: string[1] t = [ val ];
          return this;
      }
Remove the following opAssign altogether:
      Test opAssign(Test val){
          this.val = val.val;

          key ~= val.key;

          return this;
      }
As general rules: * Define a post-blit only if the code would be incorrect if you don't do that. (For example, it may be incorrect that two objects share the same array.) * Define an opAssign from the same type only if your implementation will be more efficient than the compiler's safe alternative, which happens to be "first copy, then swap." For example, instead of copying a member array, you may decide to reuse it.
      void append(Test t) {
          val ~= t.val;
          key ~= t.key;
      };
 }

 void main() {

      Test val;
      val = "test";

      Test[string] data;
      Test v;
      v = "asd";
      data["test"] = v;

      writeln(v);
      writeln(data["test"]);

      data["test"].append(val);


      writeln(data["test"].key);
      writeln("done");
 }

 Thanks,
 Bogdan
Ali
Jun 12 2013
parent reply "gedaiu" <szabobogdan yahoo.com> writes:
Hi,

How should i submit this bug?

Thanks,
Bogdan

On Wednesday, 12 June 2013 at 20:49:54 UTC, Ali Çehreli wrote:
 On 06/12/2013 01:12 PM, gedaiu wrote:

 Hi,

 Can anyone help me why this code goes wrong? I get exit code
139 with
 DMD 2.063


 import std.stdio;



 struct Test {
      string val = "";
      string[] key;

      /**
       * operator "=" overload
       */
      Test opAssign(string val){
          this.val = val;

          string[1] t;
          t = val;

          key ~= t;
Instead of the last three lines: key ~= val; However, if you really wanted a 1-element fixed-length array then: string[1] t = [ val ];
          return this;
      }
Remove the following opAssign altogether:
      Test opAssign(Test val){
          this.val = val.val;

          key ~= val.key;

          return this;
      }
As general rules: * Define a post-blit only if the code would be incorrect if you don't do that. (For example, it may be incorrect that two objects share the same array.) * Define an opAssign from the same type only if your implementation will be more efficient than the compiler's safe alternative, which happens to be "first copy, then swap." For example, instead of copying a member array, you may decide to reuse it.
      void append(Test t) {
          val ~= t.val;
          key ~= t.key;
      };
 }

 void main() {

      Test val;
      val = "test";

      Test[string] data;
      Test v;
      v = "asd";
      data["test"] = v;

      writeln(v);
      writeln(data["test"]);

      data["test"].append(val);


      writeln(data["test"].key);
      writeln("done");
 }

 Thanks,
 Bogdan
Ali
Jun 12 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/12/2013 11:56 PM, gedaiu wrote:

 How should i submit this bug?
You can reduce it to a minimal program first and then submit at http://d.puremagic.com/issues/ Here is a reduced program: struct Test { string[] keys; Test opAssign(Test rhs){ assert(this.keys !is null); assert(rhs.keys is null); keys ~= rhs.keys; return this; } } void main() { Test[string] data; Test t; data["test"] = t; } The output: core.exception.OutOfMemoryError The problem seems to be also related to struct initialization: As indicated by the asserts in opAssign, although main.t.keys is not null, rhs.keys is null. Ali
Jun 13 2013
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/13/2013 09:11 AM, Ali Çehreli wrote:
 On 06/12/2013 11:56 PM, gedaiu wrote:

  > How should i submit this bug?

 You can reduce it to a minimal program first and then submit at

    http://d.puremagic.com/issues/
Thank you for submitting it: http://d.puremagic.com/issues/show_bug.cgi?id=10356 Ali
Jun 14 2013