digitalmars.D.learn - Reading a file eats whole memory
- Emil Wojak (17/17) Oct 21 2007 Hi!
- div0 (5/25) Oct 21 2007 You are trying to read a string in, so I guess the routine is using the
- Jarrett Billingsley (17/21) Oct 21 2007 You are precisely right.
- Frank Benoit (5/25) Oct 21 2007 other had commented the file reading...
-
Emil Wojak
(26/29)
Oct 21 2007
Dnia 21-10-2007 o 17:45:54 Frank Benoit
- bearophile (4/13) Dec 08 2007 I don't understand the design of that std.file.read(): why don't return ...
- Dan (2/17) Dec 08 2007 1) It doesn't matter. You're supposed to cast it anyways based on the t...
Hi!
Could someone please explain why this code tries to eat my 1 GB memory a=
nd =
gets killed by the kernel afterwards? Eventually it prints "Error: Out o=
f =
memory" when I set ulimit on memory prior to launching the program.
The code:
import std.stream;
int main(char [][] args) {
Stream input=3Dnew File(args[0]);
char[] data;
input.read(data);
input.close();
return 0;
}
My intention was to read the executable itself, which is about 444 kB.
I'm running Linux, compiling with Digital Mars D Compiler v1.022
Oct 21 2007
Emil Wojak wrote:
Hi!
Could someone please explain why this code tries to eat my 1 GB memory
and gets killed by the kernel afterwards? Eventually it prints "Error:
Out of memory" when I set ulimit on memory prior to launching the program.
The code:
import std.stream;
int main(char [][] args) {
Stream input=new File(args[0]);
char[] data;
input.read(data);
input.close();
return 0;
}
My intention was to read the executable itself, which is about 444 kB.
I'm running Linux, compiling with Digital Mars D Compiler v1.022
You are trying to read a string in, so I guess the routine is using the
1st four bytes as a string length count. That's how tango works anyway IIRC.
--
My enormous talent is exceeded only by my outrageous laziness.
Oct 21 2007
"div0" <div0 users.sourceforge.net> wrote in message news:fffqid$1csk$1 digitalmars.com...You are trying to read a string in, so I guess the routine is using the 1st four bytes as a string length count. That's how tango works anyway IIRC. --You are precisely right. If you just want to get all the data in a file, just do: import std.file; int main(char[][] args) { ubyte[] data = cast(ubyte[])std.file.read(args[0]); return 0; } Two things: one, std.file.read returns a void[], which is a bit like D's equivalent of a void* -- it can point to anything, but you can't modify its data, and it also has a length which indicates the number of bytes in the data. Two, I'm casting to ubyte[] instead of char[]. Do NOT use char[] for "plain old data" as in C. char is a UTF-8 datatype, not a "one byte" datatype. You'll most likely get errors unless your input file is all plain ASCII or UTF-8 text. D provides the byte and ubyte types for raw byte data.
Oct 21 2007
Emil Wojak schrieb:
Hi!
Could someone please explain why this code tries to eat my 1 GB memory
and gets killed by the kernel afterwards? Eventually it prints "Error:
Out of memory" when I set ulimit on memory prior to launching the program.
The code:
import std.stream;
int main(char [][] args) {
Stream input=new File(args[0]);
char[] data;
input.read(data);
input.close();
return 0;
}
My intention was to read the executable itself, which is about 444 kB.
I'm running Linux, compiling with Digital Mars D Compiler v1.022
other had commented the file reading...
Using arg[0] to access the programs binary is not save, because if it is
called via the PATH variable it does not contain the path.
/proc/self/exe is a link to your executable.
Oct 21 2007
Dnia 21-10-2007 o 17:45:54 Frank Benoit <keinfarbton googlemail.com>
napisaĆ(a):
Thank you everyone for your explanations. This test below proves what you
wrote:
$ echo -en '\x03\x00\x00\x00abcdefgh' > string.dat
A test code:
-----------------
import std.stdio;
import std.stream;
int main(char [][] args) {
Stream input=new File(args[1], FileMode.In);
char[] data;
input.read(data);
writefln("data.length=", data.length, " data=", data);
input.close();
return 0;
}
-----------------
$ dmd test.d
$ ./test ./string.dat
data.length=3 data=abc
So the program reads 7 bytes - array length (4 bytes) + 3 bytes of data.
Switching type of data to ubyte[5] makes the program read exactly 5 bytes
("\x03\x00\x00\x00a").
Using arg[0] to access the programs binary is not save, because if it is
called via the PATH variable it does not contain the path.
/proc/self/exe is a link to your executable.
Well, argv[0] was just a quick and dirty test file, nevertheless thanks
for your hint :)
Oct 21 2007
Jarrett Billingsley:
import std.file;
int main(char[][] args)
{
ubyte[] data = cast(ubyte[])std.file.read(args[0]);
return 0;
}
Two things: one, std.file.read returns a void[], which is a bit like D's
equivalent of a void*
I don't understand the design of that std.file.read(): why don't return a
ubyte[] by default instead of a void[] (and cast it to everything else if you
don't need ubytes)?
Bye,
bearophile
Dec 08 2007
bearophile Wrote:Jarrett Billingsley:1) It doesn't matter. You're supposed to cast it anyways based on the type of data in the file.import std.file; int main(char[][] args) { ubyte[] data = cast(ubyte[])std.file.read(args[0]); return 0; } Two things: one, std.file.read returns a void[], which is a bit like D's equivalent of a void*I don't understand the design of that std.file.read(): why don't return a ubyte[] by default instead of a void[] (and cast it to everything else if you don't need ubytes)? Bye, bearophile
Dec 08 2007









"Jarrett Billingsley" <kb3ctd2 yahoo.com> 