On Tuesday, 20 February 2018 at 15:18:11 UTC, Adam D. Ruppe wrote:
On Tuesday, 20 February 2018 at 14:56:54 UTC, Chris M. wrote:
I'm doing this mainly for experimentation, but the following piece of code gives all sorts of errors.

so important note: this will perform worse than the automatic allocation, which just puts it down in-place. You should basically never `new` or `malloc` a `File` struct. (in fact, i think we should @disable new on it! yes, D can do that!)


    auto f = cast(File *) malloc(File.sizeof);
    *f = File("test.txt", "r");

Two notes here: 1) it will call the destructor on *f, which is uninitialized data and 2) the destructor that actually wants to run will have to wait until the GC reaps it, which is also not ideal. The segfault you see is in #2 here, though I'm not sure exactly what is causing it, could be out-of-order, could be some other corruption, idk.

Generally, when manually allocating D objects, first malloc it, then copy the `.init` value over, before casting it to the other type - do all this as bytes so it doesn't trigger postblits, destructors, etc like a real struct. The `std.conv.emplace` function from phobos does this and its source code can help you see how in a few cases.

Thanks for the info, that clears things up. Like I said, it was more experimentation rather than me planning to actually use it. Works now with the following modifications.

import std.stdio;
import core.stdc.stdlib;
import std.conv;

void main()
{
    auto f = cast(File*) malloc(File.sizeof);
    emplace!File(f, "test.txt", "r");
    f.readln.write;
    free(f);
}

    (*f).readln.writeln;

That * is unnecessary btw, in D you can

f.readln

and it will see it is a pointer to struct and dereference it for you.

That's what I had originally, but I put the * in to see if it would help with the original issue and never removed it


Reply via email to