Thread overview
Segmentation fault from using SList in a class?
Jun 06, 2015
Tim K.
Jun 06, 2015
Manfred Nowak
Jun 06, 2015
Tim K.
Jun 06, 2015
Marc Schütz
Jun 06, 2015
Tim K.
Jun 06, 2015
Panke
Jun 06, 2015
Jonathan M Davis
June 06, 2015
Hello!

I just started learning D and I come from a mostly C and C# background.
Hello World was working, so I figured that I should try something more complex: a template class and si I went with a simple stack.

Using dmd the code I wrote causes a segmentation fault and I am not sure why.

import std.stdio;
import std.container.slist;


class Stack(T)
{
    SList!(T) s;
    this() {}
    void push(T element)
    {
        s.insertFront(element);
    }
}

int main()
{
    Stack!(int) x;
    writeln("1");
    SList!(int) p;
    writeln("2");
    p.insertFront(42);
    writeln("3");
    x.push(42);
    writeln("4");
    return 0;
}


This program prints the following into the console:
% dmd test.d && ./test
1
2
3
zsh: segmentation fault  ./test


I do not understand why the normal SList works fine but the one inside the object doesn't. What am I overlooking?


Best regards,
Tim
June 06, 2015
Tim K. wrote:

>      Stack!(int) x;
x is not initialized.

`auto x= new Stack!(int);'
will do.

-manfred
June 06, 2015
On Saturday, June 06, 2015 09:44:36 Tim K. via Digitalmars-d-learn wrote:
> Hello!
>
> I just started learning D and I come from a mostly C and C#
> background.
> Hello World was working, so I figured that I should try something
> more complex: a template class and si I went with a simple stack.
>
> Using dmd the code I wrote causes a segmentation fault and I am not sure why.
>
> import std.stdio;
> import std.container.slist;
>
>
> class Stack(T)
> {
>      SList!(T) s;
>      this() {}
>      void push(T element)
>      {
>          s.insertFront(element);
>      }
> }
>
> int main()
> {
>      Stack!(int) x;
>      writeln("1");
>      SList!(int) p;
>      writeln("2");
>      p.insertFront(42);
>      writeln("3");
>      x.push(42);
>      writeln("4");
>      return 0;
> }
>
>
> This program prints the following into the console:
> % dmd test.d && ./test
> 1
> 2
> 3
> zsh: segmentation fault  ./test
>
>
> I do not understand why the normal SList works fine but the one inside the object doesn't. What am I overlooking?

>From the looks of it, you never initialized x, so it's null. So, the problem
has nothing to do with SList. It's the fact that you're trying to dereference a null reference. You need to call new to allocate a Stack!int, not just declare a reference to one.

void main()
{
    Stack!int x
    x.push(42);
}

would have exactly the same problem. You need something like

auto x = new Stack!int;

- Jonathan M Davis

June 06, 2015
On Saturday, 6 June 2015 at 10:10:15 UTC, Manfred Nowak wrote:
> x is not initialized.
>
> `auto x= new Stack!(int);'
> will do.

Thank you two.
But that leads me to another question: Why do I need to initialize x with a "new Stack" but I don't need to initialize p with a "new SList"?

Best regards,
Tim
June 06, 2015
On Saturday, 6 June 2015 at 10:16:12 UTC, Tim K. wrote:
> On Saturday, 6 June 2015 at 10:10:15 UTC, Manfred Nowak wrote:
>> x is not initialized.
>>
>> `auto x= new Stack!(int);'
>> will do.
>
> Thank you two.
> But that leads me to another question: Why do I need to initialize x with a "new Stack" but I don't need to initialize p with a "new SList"?

Because `SList` is a struct, which is a value type that is allocated where you declare it (here on the stack), while you used a class, which is a reference type and has to be allocated with `new`.

You can also turn your `Stack` type into a struct, then it works, too. (You just need to remove the constructor, which is empty anyway.)
June 06, 2015
On Saturday, 6 June 2015 at 10:20:34 UTC, Marc Schütz wrote:

> Because `SList` is a struct, which is a value type that is allocated where you declare it (here on the stack), while you used a class, which is a reference type and has to be allocated with `new`.
>
> You can also turn your `Stack` type into a struct, then it works, too. (You just need to remove the constructor, which is empty anyway.)

That makes sense. I overlooked that in SList's documentation and thought it was just a regular old class, too.

Best regards,
Tim
June 06, 2015
On Saturday, 6 June 2015 at 10:16:12 UTC, Tim K. wrote:
> On Saturday, 6 June 2015 at 10:10:15 UTC, Manfred Nowak wrote:
>> x is not initialized.
>>
>> `auto x= new Stack!(int);'
>> will do.
>
> Thank you two.
> But that leads me to another question: Why do I need to initialize x with a "new Stack" but I don't need to initialize p with a "new SList"?
>
> Best regards,
> Tim

Best way to construct a std.container is to use std.container.make.