peculiarities with char[] and std.string
xs0
xs0 at xs0.com
Mon Jun 19 07:02:45 PDT 2006
Kyle K wrote:
> Greetings.
>
> I was poking around the std.string lib, and was wondering if someone could
> answer a few questions about it. I'm relatively new to D, so I'm sure there are
> pretty obvious answers.
>
> I notice in most of the functions like toStringz() and tolower() it implements
> the copy-on-write convention... but since the default function parameter is in,
> is there not already an implicit copy of the data being made?
No, just a copy of the _reference_ is made, but both point to the same data.
> For example,
>
> import std.stdio;
> int main()
> {
> char []str, str2;
> str="foo";
> str2= bob(str);
> writefln("%s:%s", str, str2); // should print "foo:keke"
> return 0;
> }
> char []bob(in char[] str)
> {
> str = "keke";
> return str;
> }
>
> Works fine with my copy of DMD. Is this behavior not to be relied on as you
> shouldn't ever touch memory you didnt allocate (according to the FAQ)?
Well, you didn't touch the memory you didn't allocate :) If you had
char[] bob(in char[] str)
{
str[0] = 'a';
return str;
}
You'd get "aoo:aoo" as output (or a crash, as you can't write into
constants on some platforms)
> Also, why is the following the case:
>
> printf("%s", "hello\0"); // Fails with access violation
> printf("%s", cast(char *)"hello\0"); // OK
>
> Is the implicit casting from char[] to char * doing something im not aware of in
> terms of the length of the string, like chopping off the \0?
"hello\0" is a D char[] array, which is composed of length + char*.
printf doesn't know about D arrays, so it takes the length to be the
pointer to data, which fails for obvious reasons. When you cast it to
char*, you lose the length, keep the pointer, and it works. I think you
should use something like
printf("%.*s", "hello"); // no zero needed/wanted in this case..
Better yet, use writef/ln instead - it knows all about D's types..
> My last question is which is the preferred method of making a copy of a string?
> Suppose I want str2 to be a copy of str, then:
>
> str2.length = str.length;
> str2[] = str;
> // These two equivalent?
> str2 = str.dup;
Generally, .dup is/could/should be faster, as it's obvious you want a
copy, so there's no need to initialize the destination array on
resizing, for example.
Hope that helped :)
xs0
More information about the Digitalmars-d-learn
mailing list