strcpy implementation

Discussion in 'C Programming' started by iC and iC++, Jun 2, 2010.

  1. iC and iC++

    iC and iC++ Guest

    I found this code in a very old book about pointers and I started
    playing with it and I have a question.


    #include <stdio.h>
    #include <string.h>

    main()
    {
    char x[5];
    strcpy(x, "COMPILER");

    printf("%s, %u, %d, \n", x, &x, sizeof(x));

    getchar();
    }

    How deos strcpy assign all the characters in the code if x is only
    defines as a 5 byte array? In other words, where are the extra bytes
    stored and how is memory for them allocated. I looked at it while
    debugging and there were no clues there.

    thanks
     
    iC and iC++, Jun 2, 2010
    #1
    1. Advertising

  2. "iC and iC++" <> writes:

    > I found this code in a very old book about pointers and I started
    > playing with it and I have a question.


    What's its name?

    > #include <stdio.h>
    > #include <string.h>
    >
    > main()


    int main(void) is better.

    > {
    > char x[5];
    > strcpy(x, "COMPILER");


    See below for my comments on this.

    > printf("%s, %u, %d, \n", x, &x, sizeof(x));


    Only one of the formats (%s) matches the type of supplied argument and
    even that one (because of the strcpy error) won't necessarily print
    correctly. What does the book claim is being illustrated here?

    > getchar();


    There should be a return statement here.

    > }
    >
    > How deos strcpy assign all the characters in the code if x is only
    > defines as a 5 byte array? In other words, where are the extra bytes
    > stored and how is memory for them allocated. I looked at it while
    > debugging and there were no clues there.


    There are two ways to look at this. You can work out what happens on
    one particular machine when the code is compiled with one particular
    compiler and linked with one particular library; or you can look at it
    is an incorrect program whose behaviour is not specified by the language
    it appears to be written in.

    The first can be useful but I don't think it will be in this case. The
    second makes you focus on what constructs have well-defined meanings and
    that is usually more productive. Here the lesson is that strcpy must
    always have somewhere to cpy the str to.

    --
    Ben.
     
    Ben Bacarisse, Jun 2, 2010
    #2
    1. Advertising

  3. iC and iC++

    iC and iC++ Guest

    On Jun 2, 6:44 pm, Richard Heathfield <> wrote:
    > iC and iC++ wrote:
    > > I found this code in a very old book about pointers and I started
    > > playing with it and I have a question.

    >
    > > #include <stdio.h>
    > > #include <string.h>

    >
    > > main()
    > >    {
    > >    char x[5];
    > >    strcpy(x, "COMPILER");

    >
    > >    printf("%s, %u, %d, \n", x, &x, sizeof(x));

    >
    > >    getchar();
    > > }

    >
    > >  How deos strcpy assign all the characters in the code if x is only
    > > defines as a 5 byte array?

    >
    > It can't (legally). If you don't provide enough storage in the target
    > string to keep a copy of the source string, the behaviour of your
    > program is undefined. In other words, by failing to provide sufficient
    > storage you are breaking the contract between yourself and the
    > implementation, and the implementation is therefore free to break the
    > contract itself in any way it pleases.
    >
    > > In other words, where are the extra bytes
    > > stored and how is memory for them allocated. I looked at it while
    > > debugging and there were no clues there.

    >
    > A debugger can't teach you the rules of the language! There are no extra
    > bytes (in the abstract machine) - in practice, strcpy just starts
    > writing at x[0] and keeps going until it gets to a null character, so
    > any data stored immediately after x[4] are going to get trashed.
    >
    > --
    > Richard Heathfield <http://www.cpax.org.uk>
    > Email: -http://www. +rjh@
    > "Usenet is a strange place" - dmr 29 July 1999
    > Sig line vacant - apply within


    Thats what I thought too, but it actually returns "COMPILER". That
    definitely more characters than it has been allocated. Why isn't there
    an error when there should be one. I am just curious.
     
    iC and iC++, Jun 2, 2010
    #3
  4. iC and iC++

    Default User Guest

    "iC and iC++" <> wrote in message
    news:...
    >I found this code in a very old book about pointers and I started
    > playing with it and I have a question.
    >
    >
    > #include <stdio.h>
    > #include <string.h>
    >
    > main()
    > {
    > char x[5];
    > strcpy(x, "COMPILER");
    >
    > printf("%s, %u, %d, \n", x, &x, sizeof(x));
    >
    > getchar();
    > }
    >
    > How deos strcpy assign all the characters in the code if x is only
    > defines as a 5 byte array? In other words, where are the extra bytes
    > stored and how is memory for them allocated. I looked at it while
    > debugging and there were no clues there.


    It's undefined behavior. There is no defined behavior for undefined
    behavior. A possible outcome would be to keep writing until it either
    overwrote some other variables or intruded upon storage for which it had no
    permission to access, triggering some sort of system response.

    I would recommend not using that book.



    Brian
     
    Default User, Jun 2, 2010
    #4
  5. iC and iC++

    iC and iC++ Guest

    On Jun 2, 6:44 pm, Ben Bacarisse <> wrote:
    > "iC and iC++" <> writes:
    >
    > > I found this code in a very old book about pointers and I started
    > > playing with it and I have a question.

    >
    > What's its name?
    >
    > > #include <stdio.h>
    > > #include <string.h>

    >
    > > main()

    >
    > int main(void) is better.
    >
    > >    {
    > >    char x[5];
    > >    strcpy(x, "COMPILER");

    >
    > See below for my comments on this.
    >
    > >    printf("%s, %u, %d, \n", x, &x, sizeof(x));

    >
    > Only one of the formats (%s) matches the type of supplied argument and
    > even that one (because of the strcpy error) won't necessarily print
    > correctly.  What does the book claim is being illustrated here?
    >
    > >    getchar();

    >
    > There should be a return statement here.
    >
    > > }

    >
    > >  How deos strcpy assign all the characters in the code if x is only
    > > defines as a 5 byte array? In other words, where are the extra bytes
    > > stored and how is memory for them allocated. I looked at it while
    > > debugging and there were no clues there.

    >
    > There are two ways to look at this.  You can work out what happens on
    > one particular machine when the code is compiled with one particular
    > compiler and linked with one particular library; or you can look at it
    > is an incorrect program whose behaviour is not specified by the language
    > it appears to be written in.
    >
    > The first can be useful but I don't think it will be in this case.  The
    > second makes you focus on what constructs have well-defined meanings and
    > that is usually more productive.  Here the lesson is that strcpy must
    > always have somewhere to cpy the str to.
    >
    > --
    > Ben.


    The point this book is trying to make is as follows:
    ..."x does not equal "COMPILER". It only returns the memory address
    at which the first character in the array is stored. Function that
    accept this pointer are programmed to be "smart" and know to quit when
    what they are doing after reading the NULL character."

    So, even though, x only contains the first 5 bytes, the next 3 are
    copied and when printf prints x, it continues past the 5th bit and
    does not stop until the NULL is reached, as in this case.
     
    iC and iC++, Jun 2, 2010
    #5
  6. iC and iC++

    bart.c Guest

    iC and iC++ wrote:
    > On Jun 2, 6:44 pm, Richard Heathfield <> wrote:
    >> iC and iC++ wrote:


    >>> char x[5];
    >>> strcpy(x, "COMPILER");

    >>
    >>> printf("%s, %u, %d, \n", x, &x, sizeof(x));


    >>> How deos strcpy assign all the characters in the code if x is only
    >>> defines as a 5 byte array?

    >>
    >> It can't (legally). If you don't provide enough storage in the target


    > Thats what I thought too, but it actually returns "COMPILER". That
    > definitely more characters than it has been allocated. Why isn't there
    > an error when there should be one. I am just curious.


    It works by chance. Whatever is being overwritten with the extra 4 bytes,
    hasn't caused a crash or malfunction in this case (although you might want
    to check the files on your hard drive are all still there..)

    (Try a much longer string than "compiler". And/or a different compiler.)

    C doesn't provide these safeguards except perhaps in certain
    implementations.

    --
    Bartc
     
    bart.c, Jun 3, 2010
    #6
  7. iC and iC++

    iC and iC++ Guest

    On Jun 2, 7:07 pm, Richard Heathfield <> wrote:
    > iC and iC++ wrote:
    > > On Jun 2, 6:44 pm, Richard Heathfield <> wrote:
    > >> iC and iC++ wrote:

    >
    > <snip>
    >
    > >>>    char x[5];
    > >>>    strcpy(x, "COMPILER");
    > >>>    printf("%s, %u, %d, \n", x, &x, sizeof(x));
    > >>>    getchar();
    > >>> }
    > >>>  How deos strcpy assign all the characters in the code if x is only
    > >>> defines as a 5 byte array?

    >
    > <snip>
    >
    > >> [...] in practice, strcpy just starts
    > >> writing at x[0] and keeps going until it gets to a null character, so
    > >> any data stored immediately after x[4] are going to get trashed.

    >
    > > Thats what I thought too, but it actually returns "COMPILER".

    >
    > When you break the rules, anything can happen, including what you
    > observed to happen (but that isn't the only thing that could have happened).
    >
    > > That
    > > definitely more characters than it has been allocated. Why isn't there
    > > an error when there should be one. I am just curious.

    >
    > There *is* an error. The error is in the code. But this isn't the kind
    > of error a compiler can catch (in the general case). It's what we know
    > in the trade as a "bug".
    >
    > Let's just play pretend for a moment. Let's pretend that memory is laid
    > out like this:
    >
    > +-----+-----+-----+-----+-----+-----+-----+-----+-----+
    > |     |     |     |     |     |     |     |     |     |
    > +-----+-----+-----+-----+-----+-----+-----+-----+-----+
    > <-- 5 bytes reserved for x --> <-- 4 bytes reserved
    >                                     for system time -->
    >
    > (In practice, no system would be daft enough to keep its timestamp so
    > close to user memory, but we're just pretending.)
    >
    > First, let's take a look at our system time:
    >
    > *) TIME
    > 17:42
    >
    > Now let's run our program:
    >
    > *) SILLYSTRCPY
    >
    > When your program starts its run (on this pretend system), x contains
    > any old junk, whatever happened to be in memory, and the following four
    > bytes contain the system time (which, for simplicity, I'll represent in
    > ASCII).
    >
    > +-----+-----+-----+-----+-----+-----+-----+-----+-----+
    > |  d  |  %  |  $  |  `  |  &  |  1  |  7  |  4  |  2  |
    > +-----+-----+-----+-----+-----+-----+-----+-----+-----+
    > <-- 5 bytes reserved for x --> <-- 4 bytes reserved
    >                                     for system time -->
    >
    > Now we execute our strcpy, and here's what happens to the memory (on
    > this particular system):
    >
    > +-----+-----+-----+-----+-----+-----+-----+-----+-----+
    > |  C  |  O  |  M  |  P  |  I  |  L  |  E  |  R  |  \0 |
    > +-----+-----+-----+-----+-----+-----+-----+-----+-----+
    > <-- 5 bytes reserved for x --> <-- 4 bytes reserved
    >                                     for system time -->
    >
    > We print the string, and printf thinks it's just a string like any
    > other, so printf prints everything from the start of x up to the first
    > null character, and you see:
    >
    > COMPILER
    >
    > on your monitor. The program then ends, and we are back at the prompt:
    >
    > *)
    >
    > We are curious to know again what the time is, so we do this:
    >
    > *) TIME
    >
    > and the result is:
    >
    > LER
    >
    > The program has trashed an important component of the system by
    > violating the bounds of its memory. Lesson: Don't Do That.
    >
    > --
    > Richard Heathfield <http://www.cpax.org.uk>
    > Email: -http://www. +rjh@
    > "Usenet is a strange place" - dmr 29 July 1999
    > Sig line vacant - apply within


    you have been understood.

    thanks
     
    iC and iC++, Jun 3, 2010
    #7
  8. iC and iC++ <> wrote:
    > I found this code in a very old book about pointers and I started
    > playing with it and I have a question.


    > #include <stdio.h>
    > #include <string.h>


    > main()
    > {
    > char x[5];
    > strcpy(x, "COMPILER");


    > printf("%s, %u, %d, \n", x, &x, sizeof(x));


    > getchar();
    > }


    > How deos strcpy assign all the characters in the code if x is only
    > defines as a 5 byte array? In other words, where are the extra bytes
    > stored and how is memory for them allocated. I looked at it while
    > debugging and there were no clues there.


    You won't find anything because this use of strcpy() just in-
    vokes undefined behaviour. As a programmer you have to ensure
    that the buffer you pass to strcpy() as the target is large
    enough to hold the string you want to copy to it. In this pro-
    gram this isn't the case and the consequences could be anything
    - from looking as if everything works fine, a crash of your pro-
    gram to your hard disk getting reformatted. So this example
    program simply is buggy and should be marked with "Don't do
    this at home. kids".

    strcpy() simply doesn't have any means of checking if the
    source string will fit into the target buffer - all it gets
    is two pointers with no information about the sizes of the
    buffers. So it has to blindly trust you that you have got
    it right and copies everything, including the trailing '\0'
    char, from the source string to the destination. If the desti-
    nation buffer is too short printf() will blissfully ignorant
    of what may be the consequences overwrite the memory following
    the end of the destination buffer. If there's something im-
    portant to your program (or even the operating system) you
    just overwrote it and there's no way to get it back. strcpy()
    also can only deduce from the trailing '\0' in the source
    buffer when to stop, so if you pass it a char array that
    doesn't contain a '\0' (so it's not a string) then you're also
    screwed since it won't stop at the end of the source buffer
    but happily continues until it finds some '\0' in the memory
    following the end of the source buffer.

    Perhaps that gets even more clear if you consider a possible
    implemention of strcpy():

    char *strcpy( char *dest, const char *src )
    {
    char *ret = dest;
    while ( *dest++ = *src++ );
    return ret;
    }

    This is (I think) a perfectly legal implementation of strcpy().
    So you will be in trouble when

    a) 'dest' is a NULL pointer or does not point to memory you own
    b) 'src' is a NULL pointer or does not point to memory you own
    c) 'src' isn't a pointer to a string, i.e. there's no '\0'
    within the elements of the char array pointed to by 'src'
    d) the char array 'dest' is pointing to isn't large enough
    to hold all the chars from 'src' up to and including
    the terminating '\0; char

    So YOU have to take care that this can't happen. You pro-
    bably will be careless a few times and will have to spend
    a god deal of time figuring out where things went wrong.
    In the long run it will make you either a much more careful
    programmer or you will switch to a language where this can't
    happen. It's like with cooking - things are a lot more fun
    if you have really sharp knifes but you have to be on your
    toes or you will shed some of your blood (or even lose parts
    of your fingers;-)

    By the way, also this line is problematic:

    > printf("%s, %u, %d, \n", x, &x, sizeof(x));


    since the type of 'sizeof(x) isn't necessarily an int
    (as you are promising printf() by using the '%d' format
    specifier). The result of 'sizeof' is an unsigned integer
    type of 'size_t' (note the 'integer' in contrast to 'int'),
    so it would be prudent to use '%lu' as the format specifier
    and cast the result of 'sizeof' to 'unsigned long' (or use
    whatever is the largest unsigned integer type on your machine
    unless you have a C99 compliant compiler where there's the
    special format specifier of '%z' that tells printf() that it
    has to expect a type of 'size_t' as the corresponding argument).

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Jun 3, 2010
    #8
  9. iC and iC++

    iC and iC++ Guest

    On Jun 2, 7:18 pm, Geoff <> wrote:
    > On Wed, 2 Jun 2010 15:57:34 -0700 (PDT), "iC and iC++"
    >
    >  What is the title of this book and who is the author?


    Mastering C Pointers: Tools for programming power by Robert J.
    Traister.. 1990

    I am writing a tutorial on C pointers and this is one of the better
    books I've found..
     
    iC and iC++, Jun 3, 2010
    #9
  10. iC and iC++

    Seebs Guest

    On 2010-06-02, iC and iC++ <> wrote:
    > #include <stdio.h>
    > #include <string.h>
    >
    > main()
    > {
    > char x[5];
    > strcpy(x, "COMPILER");
    >
    > printf("%s, %u, %d, \n", x, &x, sizeof(x));
    >
    > getchar();
    > }


    > How deos strcpy assign all the characters in the code if x is only
    > defines as a 5 byte array?


    By overwriting other stuff, probably. This is certainly welcome to blow up
    spectacularly, and will on some hardware.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Jun 3, 2010
    #10
  11. iC and iC++

    Seebs Guest

    On 2010-06-02, iC and iC++ <> wrote:
    > I am writing a tutorial on C pointers and this is one of the better
    > books I've found..


    If you are at a level of expertise where you have to ask these questions,
    I respectfully submit that you are probably not the right person to be
    writing a tutorial on C pointers.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Jun 3, 2010
    #11
  12. "iC and iC++" <> writes:
    [...]
    >> iC and iC++ wrote:
    >> > I found this code in a very old book about pointers and I started
    >> > playing with it and I have a question.

    >>
    >> > #include <stdio.h>
    >> > #include <string.h>

    >>
    >> > main()
    >> >    {
    >> >    char x[5];
    >> >    strcpy(x, "COMPILER");

    >>
    >> >    printf("%s, %u, %d, \n", x, &x, sizeof(x));

    >>
    >> >    getchar();
    >> > }

    >>
    >> >  How deos strcpy assign all the characters in the code if x is only
    >> > defines as a 5 byte array?

    [snip]
    >
    > Thats what I thought too, but it actually returns "COMPILER". That
    > definitely more characters than it has been allocated. Why isn't there
    > an error when there should be one. I am just curious.


    There was an error. It just wasn't detected.

    But I think what you meant was "Why isn't there an error *message*".

    Many errors in C are classified as "undefined behavior". This means
    that it's something you shouldn't do, but the implementation is not
    obligated to diagnose, or even detect, the problem. Almost all
    languages have such things; C has more than most. It can make C
    programming tricky. Trial and error can often lead you astray;
    a program that appears to work can still have serious errors.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 3, 2010
    #12
  13. "iC and iC++" <> writes:

    > On Jun 2, 7:18 pm, Geoff <> wrote:
    >> On Wed, 2 Jun 2010 15:57:34 -0700 (PDT), "iC and iC++"
    >>
    >>  What is the title of this book and who is the author?


    There is always the possibility the code or its purpose have not been
    accurately described.

    > Mastering C Pointers: Tools for programming power by Robert J.
    > Traister.. 1990


    From the Amazon page:

    Customers Who Bought This Item Also Bought

    C: The Complete Reference, 4th Ed. by
    Herbert Schildt

    --
    Ben.
     
    Ben Bacarisse, Jun 3, 2010
    #13
  14. "iC and iC++" <> writes:
    > On Jun 2, 7:07 pm, Richard Heathfield <> wrote:

    [100 lines deleted]
    >
    > you have been understood.
    >
    > thanks


    When you post a followup, please trim the quoted text, keeping
    only enough for your followup to be reasonably clear to someone
    who hasn't read the parent article. In particular, please don't
    quote signatures (the 4 or so lines following the "-- " marker)
    unless you're actually commenting on them.

    See most of the articles in this newsgroup for good examples of
    how to do this.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 3, 2010
    #14
  15. Geoff <> writes:
    [...]
    > You MIGHT spot the bug in debug when your program prints garbage due
    > to an unterminated string if you used strncpy(), example:
    >
    > strncpy(x, "COMPILER", sizeof(x));
    >
    > But even strncpy won't save you if the memory allocated to x was
    > zero-filled prior to the copy operation.
    >
    > Short answer, forget strcpy exists. Use strncpy with care and remember
    > if the buffer size is LESS than the string to be copied strncpy won't
    > properly terminate the destination string.


    I suggest that that's bad advice.

    strncpy(), in contrast to most of the other standard strn*()
    functions, is *not* just a safer version of strcpy() that lets you
    specify a maximum length. It's designed for a very specific (and,
    these days, unusual) data structure: a fixed size characters array
    consisting of some number of data characters followed by zero or
    more trailing null characters. (Some early Unix systems stored
    file names this way, with an upper bound of 14 characters.)

    If the source string is short, the target array is padded with
    unnecessary extra null characters. If the source is long, the
    target array will not contain a string, which will almost certainly
    cause problems later on. (Whether those problems will be detected
    is another matter.)

    If you're able to exercise enough care to use strncpy() safely,
    you're able to exercise enough care to use strcpy() safely.

    strcpy() is not *inherently* dangerous. It's possible to shoot
    yourself in the foot with it (as the original example demonstrates),
    but with care it can be used safely; you just have to ensure,
    by whatever means you like, that the target array is big enough.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 3, 2010
    #15
  16. Seebs <> writes:
    > On 2010-06-02, iC and iC++ <> wrote:
    >> #include <stdio.h>
    >> #include <string.h>
    >>
    >> main()
    >> {
    >> char x[5];
    >> strcpy(x, "COMPILER");
    >>
    >> printf("%s, %u, %d, \n", x, &x, sizeof(x));
    >>
    >> getchar();
    >> }

    >
    >> How deos strcpy assign all the characters in the code if x is only
    >> defines as a 5 byte array?

    >
    > By overwriting other stuff, probably. This is certainly welcome to blow up
    > spectacularly, and will on some hardware.


    It's also welcome to quietly do what you expected it to do. This is
    arguably a much worse outcome than blowing up spectacularly.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 3, 2010
    #16
  17. iC and iC++

    Seebs Guest

    On 2010-06-03, Jason Earl <> wrote:
    > On Wed, Jun 02 2010, Seebs wrote:
    >> If you are at a level of expertise where you have to ask these
    >> questions, I respectfully submit that you are probably not the right
    >> person to be writing a tutorial on C pointers.


    > I respectfully disagree. Writing a tutorial is a great way to learn
    > something. If you think about it you'll probably even agree with me.


    No, no, I've thought about it a great deal and I still strongly disagree.

    > I would bet that you learned a great deal about shell scripting by writing
    > a book about the subject.


    Yes. But I *started* as an experienced shell programmer who knew the
    topic better than most people. And I was writing a book which, no matter
    what the marketing people thought, was aimed at reasonably experienced
    people.

    A decent tutorial is MUCH harder to write. It's aimed at people who haven't
    got the background or skills to recognize any errors you make, and who are
    unequipped to evaluate the quality of your work -- and they are fairly likely
    to imprint on whatever mistakes you make.

    > There are certainly people that know even less about pointers than iC,
    > and so tutorial could even be helpful.


    A book or tutorial written by someone even moderately experienced, but not
    an expert, can often be fairly harmful -- it's too easy to teach people
    errors.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Jun 3, 2010
    #17
  18. Seebs <> writes:
    > On 2010-06-03, Jason Earl <> wrote:
    >> On Wed, Jun 02 2010, Seebs wrote:
    >>> If you are at a level of expertise where you have to ask these
    >>> questions, I respectfully submit that you are probably not the right
    >>> person to be writing a tutorial on C pointers.

    >
    >> I respectfully disagree. Writing a tutorial is a great way to learn
    >> something. If you think about it you'll probably even agree with me.

    >
    > No, no, I've thought about it a great deal and I still strongly disagree.


    I suggest that *writing* a tutorial might be a good way to learn
    something. *Distributing* it (other than to experts for feedback)
    might not be such a good idea.

    Of course, once you've written a tutorial it might be hard to resist
    the temptation to share it -- which could explain the preponderance
    of lousy tutorials out there.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 3, 2010
    #18
  19. On 3 June, 00:09, Geoff <> wrote:
    > On Wed, 2 Jun 2010 15:22:39 -0700 (PDT), "iC and iC++"
    > <> wrote:


    > >I found this code in a very old book about pointers and I started
    > >playing with it and I have a question.

    >
    > >#include <stdio.h>
    > >#include <string.h>

    >
    > >main()
    > >    {
    > >    char x[5];
    > >    strcpy(x, "COMPILER");

    >
    > >    printf("%s, %u, %d, \n", x, &x, sizeof(x));

    >
    > >    getchar();
    > >}

    >
    > > How deos strcpy assign all the characters in the code if x is only
    > >defines as a 5 byte array? In other words, where are the extra bytes
    > >stored and how is memory for them allocated. I looked at it while
    > >debugging and there were no clues there.

    >
    > This is a fine example of why strcpy is unsafe.


    only you and Microsoft think strcpy() is unsafe. Like many other C
    functions strcpy() can be used in an unsafe manner. Either don't do
    that or use a safer language.

    > The results you get will depend on your platform and compiler
    > implementation as well as your choice of optimizations. On x86 in
    > debug mode on Windows you would have to look closely to see the bug
    > waiting to bite you.
    >
    > 5 bytes are reserved for x[] but strcpy will write 8 characters plus a
    > zero termination for the string (9 chars). Overwriting something
    > adjacent to x[] and on x86 that would be in the stack frame for the
    > main() function. Classic buffer overrun and stack smash waiting to
    > happen. If the second argument to strcpy was dependent on user input,
    > you would be in a world of hurt when the blackhats want to hit you.
    >
    > My compiler reserves 8 bytes for the 5 chars due to alignment
    > requirements.
    >
    > You MIGHT spot the bug in debug when your program prints garbage due
    > to an unterminated string if you used strncpy(), example:
    >
    >         strncpy(x, "COMPILER", sizeof(x));
    >
    > But even strncpy won't save you if the memory allocated to x was
    > zero-filled prior to the copy operation.
    >
    > Short answer, forget strcpy exists. Use strncpy with care and remember
    > if the buffer size is LESS than the string to be copied strncpy won't
    > properly terminate the destination string.- Hide quoted text -


    no. Forget strncpy() exists. This is my strncpy() boilerplate response

    the semantics of strncpy() are non-intuitive (it's broken). So
    generally
    *don't* use strncpy.

    /* what is wrong with this? */
    char sbuff[5];
    strncpy(sbuff, "bomb", 4);
    printf ("%s\n", buff);

    /* how many characters are written to bbuff? */
    char bbuff [1000000];
    strncpy(bbuff, "bomb", 1000000);

    See FAQ 13.2 "Why does strncpy() not always place a '\0'
    terminator in the destination string?
     
    Nick Keighley, Jun 3, 2010
    #19
  20. iC and iC++

    Seebs Guest

    On 2010-06-03, Keith Thompson <> wrote:
    > I suggest that *writing* a tutorial might be a good way to learn
    > something. *Distributing* it (other than to experts for feedback)
    > might not be such a good idea.


    That may be a good point.

    My experience has been that trying to teach something before I understand
    it well enough tends to make me firm up bad ideas, though, because I have
    to talk as though they're known truths rather than speculations...

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Jun 3, 2010
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike Mimic

    strcpy

    Mike Mimic, May 16, 2004, in forum: C++
    Replies:
    9
    Views:
    814
    Peter Koch Larsen
    May 17, 2004
  2. Paul Sheer
    Replies:
    7
    Views:
    495
    Paul Sheer
    Sep 10, 2004
  3. Paul Sheer
    Replies:
    4
    Views:
    644
    Paul Sheer
    Sep 14, 2004
  4. RonHiler
    Replies:
    8
    Views:
    523
    John Harrison
    Oct 19, 2004
  5. arnuld

    strcpy - my implementation

    arnuld, Sep 8, 2008, in forum: C Programming
    Replies:
    64
    Views:
    1,563
    Keith Thompson
    Sep 11, 2008
Loading...

Share This Page