strcpy question

Discussion in 'C Programming' started by Jack, Jun 1, 2006.

  1. Jack

    Jack Guest

    The following code causes "Segementation fault":

    char *s1;
    char *s2;

    s2 = "HELLO";

    strcpy(s1, s2);

    If I modify the code to:

    char *s1;
    char *s2;

    s2 = "HELLO";

    s1 = (char*)malloc(10 * sizeof(char));

    strcpy(s1, s2);

    The code works well. So I should always allocate memory for s1, before
    I call strcpy, right?

    Thanks.
     
    Jack, Jun 1, 2006
    #1
    1. Advertising

  2. In article <>,
    Jack <> wrote:
    >The following code causes "Segementation fault":


    >char *s1;
    >char *s2;


    >s2 = "HELLO";


    >strcpy(s1, s2);


    You have declared s1 to be a pointer, but you haven't given it
    any memory to point to.


    >If I modify the code to:
    >
    >char *s1;
    >char *s2;
    >
    >s2 = "HELLO";
    >
    >s1 = (char*)malloc(10 * sizeof(char));
    >
    >strcpy(s1, s2);
    >
    >The code works well. So I should always allocate memory for s1, before
    >I call strcpy, right?


    Not necessarily. For example,

    char s1[128];
    char *s2 = "HELLO";
    if (strlen(s2) => sizeof s1) fprintf(stderr, "Opps, s2 is too long\n")
    else strcpy(s1,s2);

    The key is that the destination storage must exist before you can write
    into it. malloc() is one way of getting that storage, but you can also
    write into auto or static variables as long as you make sure you do
    not write past the end of the variable.
    --
    "law -- it's a commodity"
    -- Andrew Ryan (The Globe and Mail, 2005/11/26)
     
    Walter Roberson, Jun 1, 2006
    #2
    1. Advertising

  3. Jack said:

    > The following code causes "Segementation fault":
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > strcpy(s1, s2);


    Yeah, it would.

    > If I modify the code to:
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > s1 = (char*)malloc(10 * sizeof(char));


    s1 = malloc(strlen(s2) + 1);
    if(s1 != NULL)
    {

    > strcpy(s1, s2);
    >
    > The code works well. So I should always allocate memory for s1, before
    > I call strcpy, right?


    Yeah. Everything Has To Be Somewhere. You have to have somewhere to put it,
    before you can put it there.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Jun 1, 2006
    #3
  4. Jack

    Eric Sosman Guest

    Jack wrote On 06/01/06 16:28,:
    > The following code causes "Segementation fault":
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > strcpy(s1, s2);
    >
    > If I modify the code to:
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > s1 = (char*)malloc(10 * sizeof(char));
    >
    > strcpy(s1, s2);
    >
    > The code works well. So I should always allocate memory for s1, before
    > I call strcpy, right?


    See Questions 7.1, 7.2, and 7.3b in the comp.lang.c
    Frequently Asked Questions (FAQ) list

    http://www.c-faq.com/

    --
     
    Eric Sosman, Jun 1, 2006
    #4
  5. "Jack" <> writes:
    > The following code causes "Segementation fault":
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > strcpy(s1, s2);
    >
    > If I modify the code to:
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > s1 = (char*)malloc(10 * sizeof(char));
    >
    > strcpy(s1, s2);
    >
    > The code works well. So I should always allocate memory for s1, before
    > I call strcpy, right?


    Yes, of course.

    Another point: the line
    s1 = (char*)malloc(10 * sizeof(char));
    is better written as
    s1 = malloc(10);
    Casting the result of malloc() is unnecessary and can mask errors.
    sizeof(char) is 1 by definition.

    (And, if you haven't already, please read
    <http://cfaj.freeshell.org/google/>.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Jun 1, 2006
    #5
  6. -cnrc.gc.ca (Walter Roberson) writes:
    > In article <>,
    > Jack <> wrote:

    [...]
    >>If I modify the code to:
    >>
    >>char *s1;
    >>char *s2;
    >>
    >>s2 = "HELLO";
    >>
    >>s1 = (char*)malloc(10 * sizeof(char));
    >>
    >>strcpy(s1, s2);
    >>
    >>The code works well. So I should always allocate memory for s1, before
    >>I call strcpy, right?

    >
    > Not necessarily. For example,
    >
    > char s1[128];
    > char *s2 = "HELLO";
    > if (strlen(s2) => sizeof s1) fprintf(stderr, "Opps, s2 is too long\n")
    > else strcpy(s1,s2);
    >
    > The key is that the destination storage must exist before you can write
    > into it. malloc() is one way of getting that storage, but you can also
    > write into auto or static variables as long as you make sure you do
    > not write past the end of the variable.


    I assumed that declaring s1 as an array object qualifies as
    "allocating memory", but it's an important distinction. The memory
    has to exist; how it's allocated is another question.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Jun 1, 2006
    #6
  7. Jack

    CBFalconer Guest

    CBFalconer, Jun 1, 2006
    #7
  8. Jack

    Tomás Guest

    Jack posted:

    > The following code causes "Segementation fault":
    >
    > char *s1;
    > char *s2;



    When you define a variable within a function without initialising it, it
    contains white noise -- a bit-pattern left over from the last time that
    memory was used. (Except if the object is static... but I won't get into
    that just now).

    An int variable holds an integer numerical value.

    A pointer variable holds a memory address.

    You define "s1" without initialising it -- as far as you're concerned, it
    contains a random value. For the purpose of this demonstration, let's
    assume that this "random memory address" is 2349538.

    You also define "s2" without initialising it, but that's okay because you
    set its value soon after.


    > s2 = "HELLO";



    "s2" now contains the memory address of the first char in that string
    literal. (I would advocate using pointer-to-const for this purpose).


    > strcpy(s1, s2);



    You copy the string located at the memory address specified by s2 to the
    memory address specified by s1. So basically you're copying "Hello" to
    our random memory address of 2349538.

    The memory address 2349538 isn't yours to access -- it could contain
    important data.


    > If I modify the code to:
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > s1 = (char*)malloc(10 * sizeof(char));



    Here you allocate 10 bytes of memory.

    You then set the value of "s1" to the address of the first byte.

    "s1" no longer contains a random value -- it contains a legitimate value;
    you allocated those 10 bytes, and now you're free to use them in whatever
    way you please.


    > strcpy(s1, s2);



    Here you copy "Hello" to the address specified by "s1". The address
    specified by "s1" is the 10 bytes of memory you allocated. This is fine.


    > The code works well. So I should always allocate memory for s1, before
    > I call strcpy, right?



    I find it handy to repeat to yourself, "A pointer stores a memory
    address".

    If you're going to be accessing the data stored at a memory address, you
    must make sure you are allowed access the memory in question.


    -Tomás
     
    Tomás, Jun 2, 2006
    #8
  9. Jack

    Haider Guest

    Jack wrote:
    > The following code causes "Segementation fault":
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > strcpy(s1, s2);
    >
    > If I modify the code to:
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > s1 = (char*)malloc(10 * sizeof(char));
    >
    > strcpy(s1, s2);
    >
    > The code works well. So I should always allocate memory for s1, before
    > I call strcpy, right?
    >
    > Thanks.

    Yes you have to. there must be memory and has to be large enough to
    hold the value.
     
    Haider, Jun 2, 2006
    #9
  10. Jack

    santosh Guest

    Jack wrote:
    > The following code causes "Segementation fault":
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > strcpy(s1, s2);
    >
    > If I modify the code to:
    >
    > char *s1;
    > char *s2;
    >
    > s2 = "HELLO";
    >
    > s1 = (char*)malloc(10 * sizeof(char));
    >
    > strcpy(s1, s2);
    >
    > The code works well. So I should always allocate memory for s1, before
    > I call strcpy, right?


    You should always set any pointer to a valid region of memory or other
    data structure before any operations upon it. In the meantime, you can
    make it a null pointer.
     
    santosh, Jun 2, 2006
    #10
    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:
    835
    Peter Koch Larsen
    May 17, 2004
  2. Paul Sheer
    Replies:
    7
    Views:
    509
    Paul Sheer
    Sep 10, 2004
  3. Paul Sheer
    Replies:
    4
    Views:
    677
    Paul Sheer
    Sep 14, 2004
  4. herrcho

    strcpy Question

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

    strcpy question

    mdh, May 5, 2008, in forum: C Programming
    Replies:
    15
    Views:
    745
    Keith Thompson
    May 19, 2008
Loading...

Share This Page