On Tue, 30 Dec 2008 20:34:00 +0300, Michael P. <[email protected]> wrote:

Denis Koroskin Wrote:

On Tue, 30 Dec 2008 20:23:07 +0300, Michael P. <[email protected]> wrote:

> Denis Koroskin Wrote:
>
>> On Tue, 30 Dec 2008 18:56:08 +0300, Michael P. <[email protected]>
>> wrote:
>>
>> > Jarrett Billingsley Wrote:
>> >
>> >> On Mon, Dec 29, 2008 at 10:36 PM, Michael P. <[email protected]>
>> >> wrote:
>> >> > import std.stdio;
>> >> > import std.cstream;
>> >> > void main()
>> >> > {
>> >> >  char[][] names;
>> >> >  char[] currentName;
>> >> >  while( true )
>> >> >  {
>> >> >    din.readf( "%s", &currentName );
>> >> >    if( currentName == "stop" )
>> >> >    {
>> >> >      break;
>> >> >    }
>> >> >    else
>> >> >    {
>> >> names ~= currentName;
>> >> >    }
>> >> >  }
>> >> >  foreach( name; names )
>> >> >  {
>> >> >    writefln( name );
>> >> >  }
>> >> > }
>> >>
>> >> ~= performs an append.  It adds the given item to the end of the
>> array.
>> >
>> > Under 1.036, this does not work.
>> >
>> > Input:
>> > michael
>> > is
>> > cool
>> > stop
>> >
>> > The output is:
>> > stopeal
>> > st
>> > stop
>> >
>> > What seems to be happening is that the letters of stop are added to
>> the
>> > word, and if the word is longer than stop, then the rest of the
>> letters
>> > of the word are added.
>> > So, I'm not sure if this is a bug or what...
>> > -Michael P.
>>
>> Now, it's not. What you do is overwrite the string again and again.
>> Try putting "currentName = null;" before doing din.readf().
>
> Thanks, that worked.
> -Michael P.

Did you understand the difference? Can you explain the behavior (to yourself)?

Not really... I really have no idea why it wouldn't work before.

Well, let's go through the code.

First of all, you should undestand that an array is nothing but a pair of 
pointer to first element and its length.

Since char[] == string in D1, let's use string instead to make code slightly 
more readable.

string[] names; // array of strings that will store our names
string currentName;
...
din.readf( "%s", &currentName ); // what does this line do?

din.readf tries to minimize allocations by accepting a buffer where the string 
will be stored. Buffer will be allocated on heap if provided one is too small 
to fit the whole string.

Initially, currentName is null, i.e. currentName.ptr is null and currentName.length == 0. 
If you type anything, the data won't fit into buffer and therefore a new one is created 
by readf. When you return from readf, currentName will point to "michael" and 
have length == 7.

When you call din.readf for second time, you pass your currentName as a buffer once again. This time it is large enough 
to fit "is" and therefore it is not reallocated. "is" is written on top of "michael" and 
becomes "ischael". currentName's length is updated to 2. Etc.

Here is names' contents step by step:

At Startup:
string[] names = []; // empty

Step 1:
string[] names = [ "michael" ];

Step 2:
string[] names = [ "ischael", "is" ];

Step 3:
string[] names = [ "coolael", "co", "cool" ];

Step 4:
string[] names = [ "stopael", "st", "stop", "stop" ];

When you reset buffer (by doing "currentName = null;"), a new one is allocated 
each step and each string gets its own memory. That's it.

Reply via email to