strcpy question

Discussion in 'C Programming' started by mdh, May 5, 2008.

  1. mdh

    mdh Guest

    I have a question about the library function strcpy.
    In K&R on page 109, strcpy is used to copy a line ( line[] ) to a
    pointer (char *), which is first allocated space by K&Rs "alloc"
    function.
    In a few pages prior to this, the example that K&R showed used this
    definition for it's version of strcpy

    void strcpy( char *s, char *t){

    while ( *s++ = *t++);

    }

    Could someone help me understand the library function, which,
    according to the appendix, returns the target string.
    So, in this case, what is passed to the library is an array-the
    original string and a pointer to the target string? What happens if
    the target pointer has not been allocated space? And, is this
    acceptable ie to pass a pointer instead of an actual char array for
    the target string?

    tks
    mdh, May 5, 2008
    #1
    1. Advertising

  2. On May 5, 7:19 pm, mdh <> wrote:

    > void strcpy( char *s, char *t){
    >
    > while ( *s++ = *t++);
    >
    > }
    >
    > Could someone help me understand the library function, which,
    > according to the appendix, returns the target string.



    Well firstly, this particular implementation of it does NOT return the
    target string.

    Let's take a look at that loop:

    while (*s++ = *t++);

    This is the same as the following:

    for (;;) /* Eternal loop */
    {
    *s = *t;

    ++s;
    ++t;

    if (!*(s-1)) break;
    }

    It copies the destination to the source, increments both pointers, and
    finally checks to see whether the last character copied was the null
    character. If so, the loop stops.


    > So, in this case, what is passed to the library is an array-the
    > original string  and a pointer to the target string? What happens if
    > the target pointer has not been allocated space? And, is this
    > acceptable ie to pass a pointer instead of an actual char array for
    > the target string?



    If you have an array as follows:

    char arr[16];

    then when you write the name of the array on its own, what you have is
    a pointer to the first element of the array, e.g.:

    char arr[16];

    char *p;

    p = arr; /* Here we have a pointer to the first element */

    (There are three special cases in which this isn't so:
    1) When sizeof is applied to the array
    2) When the addressof operator is applied to the array
    3) ...I can't actually think of it off-hand, but I'm sure I'd know
    it if I was presented with it.)

    A pointer contains a memory address. When you invoke strcpy, you're
    giving it two memory addresses, the address of the destination and the
    address of the source. If the either pointer is dodgy, you'll get
    undefined behaviour. For a pointer not to be dodgy, it must:
    1) Point to memory that belongs to you, that is, memory that you're
    allowed to access.
    2) Point to a big enough chunk of memory to store what you want it to
    store. If you go outside the boundary, you're writing to memory that
    doesn't belong to you.
    Tomás Ó hÉilidhe, May 5, 2008
    #2
    1. Advertising

  3. On May 5, 7:39 pm, Tomás Ó hÉilidhe <> wrote:

    > It copies the destination to the source


    Wups, source to destination of course..
    Tomás Ó hÉilidhe, May 5, 2008
    #3
  4. mdh

    Default User Guest

    mdh wrote:

    > I have a question about the library function strcpy.
    > In K&R on page 109, strcpy is used to copy a line ( line[] ) to a
    > pointer (char *), which is first allocated space by K&Rs "alloc"
    > function.
    > In a few pages prior to this, the example that K&R showed used this
    > definition for it's version of strcpy
    >
    > void strcpy( char *s, char *t){
    >
    > while ( *s++ = *t++);
    >
    > }
    >
    > Could someone help me understand the library function, which,
    > according to the appendix, returns the target string.


    This says, perform the loop while the expression inside results in a
    non-zero (true) value.

    The express assign the currently pointed at value of t to the current
    pointed-at element of s and increments both pointers. The result of the
    expression is the character assigned to *s. So the copy ends when *t is
    0, or the null terminator (end of string t).

    > So, in this case, what is passed to the library is an array-the
    > original string and a pointer to the target string? What happens if
    > the target pointer has not been allocated space?


    Undefined behavior.

    > And, is this
    > acceptable ie to pass a pointer instead of an actual char array for
    > the target string?


    You can't pass an array. In most contexts, the name of an array is
    converted to a pointer to the first element. That's why both arguments
    to strcpy() are pointers there.
    Default User, May 5, 2008
    #4
  5. mdh

    mdh Guest

    Thanks all who replied. I did know that an address is passed to a
    function when an array is passed as an argument, but I had not seen it
    done like this, although it makes perfect sense.So, I guess that the
    expectation of a function when getting an array as a parameter, is to
    receive a pointer, no matter how the argument is formulated ( as an
    array or pointer), with the exceptions ( of which I was unaware)
    above. Thank you again.
    mdh, May 5, 2008
    #5
  6. On May 5, 9:08 pm, mdh <> wrote:
    > Thanks all who replied. I did know that an address is passed to a
    > function when an array is passed as an argument, but I had not seen it
    > done like this, although it makes perfect sense.So, I guess that the
    > expectation of a function when getting an array as a parameter, is to
    > receive a pointer, no matter how the argument is formulated ( as an
    > array or pointer), with the exceptions ( of which I was unaware)
    > above. Thank you again.



    A function cannot take an array as a parameter. If you do the
    following:

    void Func(int arr[5])
    {

    }

    Then it's EXACTLY the same as writing:

    void Func(int *arr)
    {

    }

    Try it out:

    void Func(int arr[5])
    {
    int i;

    arr = &i; /* arr is just a pointer to int */
    }
    Tomás Ó hÉilidhe, May 5, 2008
    #6
  7. mdh

    mdh Guest

    On May 5, 2:34 pm, Tomás Ó hÉilidhe <> wrote:

    > A function cannot take an array as a parameter. If you do the
    > following:
    >
    >  


    Sorry if I was unclear...as this is what I was trying to say. In other
    words, a function that **expects** an array, will in fact **actually**
    receive a pointer as a parameter. So, what I was concentrating on was
    the syntax where a pointer that had an array allocated to it ( ie was
    not an array that had been converted to a pointer as an argument to a
    function) is just as legal a construct under as passing an array
    itself.
    mdh, May 6, 2008
    #7
  8. mdh

    mdh Guest

    > A function cannot take an array as a parameter. If you do the
    > following:
    >



    Sorry if I was unclear...as this is what I was trying to say. In
    other
    words, a function that **expects** an array, will in fact
    **actually**
    receive a pointer as a parameter. So, what I was concentrating on was
    the syntax where a pointer that had an array allocated to it ( ie was
    not an array that had been converted to a pointer as an argument to a
    function) is just as legal a construct as passing an array
    itself.
    mdh, May 6, 2008
    #8
  9. mdh

    Default User Guest

    mdh wrote:

    > On May 5, 2:34 pm, Tomas O hEilidhe <> wrote:
    >
    > > A function cannot take an array as a parameter. If you do the
    > > following:
    > >
    > >

    >
    > Sorry if I was unclear...as this is what I was trying to say. In other
    > words, a function that expects an array, will in fact actually
    > receive a pointer as a parameter.


    A function does not and cannot "expect" an array. Even if you write the
    declaration to look like an array to a human reading it, the function
    expects nothing of the sort. It expects and receives a pointer.

    void f(int p[50]);
    void f(int p[1]);
    void f(int *p);

    The above are identical to the compiler.

    > So, what I was concentrating on was
    > the syntax where a pointer that had an array allocated to it ( ie was
    > not an array that had been converted to a pointer as an argument to a
    > function) is just as legal a construct under as passing an array
    > itself.


    You can't pass an array, so yes they are equally valid.



    Brian
    Default User, May 6, 2008
    #9
  10. mdh <> writes:
    > On May 5, 2:34 pm, Tomás Ó hÉilidhe <> wrote:
    >> A function cannot take an array as a parameter. If you do the
    >> following:

    >
    > Sorry if I was unclear...as this is what I was trying to say. In other
    > words, a function that **expects** an array, will in fact **actually**
    > receive a pointer as a parameter. So, what I was concentrating on was
    > the syntax where a pointer that had an array allocated to it ( ie was
    > not an array that had been converted to a pointer as an argument to a
    > function) is just as legal a construct under as passing an array
    > itself.


    First, a point about terminology: a parameter is an object, local to a
    function, declared in the function's declaration (for example argc and
    argv in main()); an argument is an expression passed to a function in
    a call.

    There is no such thing in C as a function that expects an array.

    A C function that *looks* like it expects an array argument, such as:
    void foo(char arr[]) { /* whatever */ }
    or even
    void foo(char arr[42]) { /* whatever */ }
    actually expects a pointer argument; both of the above is exactly
    equivalent to:
    void foo(char *arr) { /* whatever */ }

    Using array *syntax* in a parameter declaration probably suggests that
    the pointer argument should point to the first element of an array,
    but any such suggestion has no more actual force than a comment.

    The fact that C allows a parameter to be declared with array syntax,
    and that such a parameter declaration is really no different from a
    pointer parameter declaration, is IMHO unfortunate. It's mildly
    convenient to be able to say that the argument is intended to be a
    (converted) array, but the cost is increased confusion.

    In a function call, it's not possible to have an expression of array
    type as an argument. Any such expression will be converted to a
    pointer, and the called function has absolutely no way of knowing
    whether such a conversion has happened. (There are contexts in which
    this conversion doesn't happen, but a function argument cannot be one
    of those contexts.)

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, May 6, 2008
    #10
  11. mdh

    mdh Guest

    On May 5, 4:23 pm, Keith Thompson <> wrote:

    >....... Any such expression will be converted to a
    > pointer, and the called function has absolutely no way of knowing
    > whether such a conversion has happened. ....



    Thanks Keith...that's what I thought, but just wanted to be sure.
    In C, is it quite common to pass a pointer to which one has allocated
    an array, as K&R do in this example?
    mdh, May 6, 2008
    #11
  12. mdh

    mdh Guest

    On May 5, 4:16 pm, "Default User" <> wrote:
    > mdh wrote:
    > > itself.

    >
    > You can't pass an array, so yes they are equally valid.
    >
    > Brian



    thank you Brian.
    mdh, May 6, 2008
    #12
  13. mdh <> writes:
    > On May 5, 4:23 pm, Keith Thompson <> wrote:
    > >....... Any such expression will be converted to a
    >> pointer, and the called function has absolutely no way of knowing
    >> whether such a conversion has happened. ....

    >
    > Thanks Keith...that's what I thought, but just wanted to be sure.
    > In C, is it quite common to pass a pointer to which one has allocated
    > an array, as K&R do in this example?


    Yes, it's extremely common; it's how arrays are usually dealt with in
    C.

    You also usually need some way to specify how big the array is, or how
    big the portion you're interested in is. For strings, this is
    generally determined by the position of the '\0' terminator. For
    other arrays, it's common to pass a second argument that specifies the
    length of the array (see, for example, the third parameter of
    memcpy()).

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, May 6, 2008
    #13
  14. mdh

    mdh Guest

    On May 5, 6:00 pm, Keith Thompson <> wrote:
    >?
    >
    > Yes, it's extremely common; it's how arrays are usually dealt with in
    > C.
    >


    thank you Keith.
    mdh, May 6, 2008
    #14
  15. On Mon, 5 May 2008 11:39:39 -0700 (PDT), Tomás Ó hÉilidhe
    <> wrote:
    <snip>
    > then when you write the name of [an] array on its own, what you have is
    > a pointer to the first element of the array, e.g.: <snip>
    > (There are three special cases in which this isn't so:
    > 1) When sizeof is applied to the array
    > 2) When the addressof operator is applied to the array
    > 3) ...I can't actually think of it off-hand, but I'm sure I'd know
    > it if I was presented with it.)
    >

    Standard C has only (those) two explicit. C++ adds typeid, and initing
    a reference (which includes passing to a reference parameter).

    And C++ explicitly specifies cases where the expression is discarded:
    full statement, cast to void, left of comma op; C instead makes those
    'void expressions' whose 'value *or designator* is discarded'
    (6.3.2.2, emphasis added) which implies that the lvalue-to-rvalue
    conversion did not happen.

    GNU C (the language compiled by GCC) adds typeof.

    <snip rest>


    - formerly david.thompson1 || achar(64) || worldnet.att.net
    David Thompson, May 19, 2008
    #15
  16. David Thompson <> writes:
    > On Mon, 5 May 2008 11:39:39 -0700 (PDT), Tomás Ó hÉilidhe
    > <> wrote:
    > <snip>
    >> then when you write the name of [an] array on its own, what you have is
    >> a pointer to the first element of the array, e.g.: <snip>
    >> (There are three special cases in which this isn't so:
    >> 1) When sizeof is applied to the array
    >> 2) When the addressof operator is applied to the array
    >> 3) ...I can't actually think of it off-hand, but I'm sure I'd know
    >> it if I was presented with it.)
    >>

    > Standard C has only (those) two explicit. C++ adds typeid, and initing
    > a reference (which includes passing to a reference parameter).


    C has three cases, only two of which can apply to array names. The
    third case (in which an expression of array type is not implicitly
    converted to a pointer to the array's first element) is a string
    literal used in an initializer to initialize an array object.

    [snip]

    --
    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, May 19, 2008
    #16
    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:
    785
    Peter Koch Larsen
    May 17, 2004
  2. Paul Sheer
    Replies:
    7
    Views:
    474
    Paul Sheer
    Sep 10, 2004
  3. Paul Sheer
    Replies:
    4
    Views:
    625
    Paul Sheer
    Sep 14, 2004
  4. herrcho

    strcpy Question

    herrcho, Sep 29, 2003, in forum: C Programming
    Replies:
    8
    Views:
    438
    Mike Wahler
    Oct 1, 2003
  5. Jack

    strcpy question

    Jack, Jun 1, 2006, in forum: C Programming
    Replies:
    9
    Views:
    405
    santosh
    Jun 2, 2006
Loading...

Share This Page