Heinz-Mario Frühbeis <
D...@earlybite.individcore.de> wrote:
> Am 27.03.2016 um 16:17 schrieb Jorgen Grahn:
> > On Sun, 2016-03-27, Heinz-Mario Frühbeis wrote:
> >> Am 27.03.2016 um 15:03 schrieb Alf P. Steinbach:
> >>> On 27.03.2016 11:17, Heinz-Mario Frühbeis wrote:
> [...]
> >> I think, I will use memmove. I love the style "bit pushing". :)
> >
> > At least use the modern C++ mechanism instead of memmove. That
> > would be std::copy or std::copy_backward.
> >
> I've made a little test and I noticed a weird<?> behaviour...:
> [Ah first]:
> Here
> <
http://www.cplusplus.com/reference/algorithm/copy/>
> is to read:
> #include <algorithm> // std::copy
> But my Test-Prog is working with 'string.h', too. Why?
> Now...
> int main(){
> char a[512];
> char *b = a;
> const char *nString = "Hallo";
This makes 'nString' point to a (const) array of char
with 6 elements, that contains the following elements
'H', 'a', 'l', 'l', 'o', '\0'
Note the terminating '\0' - otherwise it wouldn't be
a string. A C-style string is always a char arry that
conatains a '\0', indicating where the string ends. And
this terminating '\0' is used by all the functions that
operate on strings to find the end. Thus, if there's
no '\0' it's not a string and none of the functions that
accept strings as their arguments can be used!
The terminating '\0' is the only thing that indicates
the length of the strings - there's no "hidden" vari-
able where that information would be stored and could
be retrieved by the functions operating on strings!
That's an important difference to a std::string, which
does keep track of the length of a string by other means!
(That also means that you never can have a '\0' in a C-style
string - it would be interpreted as the end of the string -
while you can store '\0' characters in std::strings.)
> copy(nString, nString + (strlen(nString)), b);
Here you copy only 5 of the 6 elements from 'nString',
missing the trailing '\0' - strlen() only gives you the
number of non-'\0' characters in a string. So 'b' isn't
pointing to a string, but to a mere array of chars. What
comes after these 5 characters is pure random garbage
and you can't forsee what it will be.
What you need is
copy(nString, nString + strlen(nString) + 1, b);
to also copy the trailing '\0'. (And you also would
need to copy 6 characters when using memcpy() or the
exact same reason!)
> for(int i = 0; i < (int) strlen(b); ++i){
> cout << b[i] << "\n";
> }
This is wrong. Since you didn't copy the terminating '\0'
to what 'b' points to strlen() can't be used because what
'b' points to isn't a string (remember a char array only
is a string if it contains a '\0' somewhere!). Instead
strlen() will keep on running over the array (or even past
its end!) until it finds a '\0' somewhere by chance. Its
result thus is completely bogus. Consider that a primitive
implementation of strlen() may just look like this:
size_t strlen(const char * str) {
size_t len = 0;
while (*str++ != '\0')
len++;
return len;
}
Thus everything printed out after the first 5 chars is
simply garbage and may be different each time you run
your program.
> cout << b << " " << strlen(b) << "\n";
And neither this can work since it also will print out cha-
racters until, by chance, there's a '\0' in the memory some-
where after what 'b' points to.
> cout.flush();
By the way outputting a 'std::endl' will both print out a
'\n' and flush the stream.
> return 0;
> }
> Cout prints:
> H
> a
> l
> l
> o
> ?0 // 0 stands for '\0'
> Hallo0? 6
"?0' definitely doesn't stand for '\0'. '\0' can't be
printed. What you got there was some random garbage from
the mmeory pointed to by 'b' behind the 5 characters you
copied.
> But:
> int main(){
> char a[512];
> char *b = a;
> const char *nString = "Hallo";
> copy(nString, nString + (strlen(nString)), b);
> cout << b << " " << strlen(b) << "\n";
> cout.flush();
> return 0;
> }
> Prints out:
> Hallo 5
> Why?
Because what's in 'a' is random and one thing that can happen
is that the sixth element of 'a', when it's not initialized.
is a '\0'. So it may seem to work at times.
And, BTW, you don't need the 'b' variable at all, you
could simply use 'a' instead - in most places 'a', when
not followed by an index in square braces, is taken to
be a pointer to the first element of 'a'.
It looks a bit as if you're trying to learn C/C++ by experi-
mentation. That's the worst way because these are languages
where minor mistakes can have really bad consequences and
where there's something called "undefined behaviour" which
means that the same code can seem to work at one time and
fail the next or seem to work on one platform but fail on
a different one. And 'fail' can mean a lot more than just
the program crashing...
Regards, Jens
--
\ Jens Thoms Toerring ___
j...@toerring.de
\__________________________
http://toerring.de