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