Why Can't we copy a string to Character Pointer WHEN we can assign a string directly to it?

前端 未结 7 1548
礼貌的吻别
礼貌的吻别 2021-02-10 01:16

This code produces \"p = hello world\":

#include \"stdio.h\"
#include \"string.h\"

int main(){
    char *p;
    p=\"hello world\";
    printf(\"p is %s \\n\",p)         


        
相关标签:
7条回答
  • 2021-02-10 01:52

    There is no free lunch - you need to grab & manage memory. If you just assume that because you have access to a pointer memory should be there then you'll run into unspecified behavior (segfault likely).

    0 讨论(0)
  • 2021-02-10 01:54

    The reason is that when you declare a pointer, it doesn't actually point to anything useful. strcpy requires a block of memory for the string to be copied into. It will not do this for you automatically.

    From the documentation (emphasis mine):

    Copies the C string pointed by source into the array pointed by destination, including the terminating null character.

    To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.

    You need to make this true, as it is a precondition of the function.

    Also, in the parameters section:

    destination

    Pointer to the destination array where the content is to be copied.
    

    You need to make sure destination is a pointer to an array.

    0 讨论(0)
  • 2021-02-10 02:08

    Notice what the two working examples have in common: they have a p = line that assigns something to p. The non-working example does not do this.

    Consider this line (from the first example):

    p = "hello world";
    

    Although it might look like it's "copying a string to a char pointer", it's not. It's copying the location of a string to a pointer-to-char. That's what a pointer-to-char like p stores - the location of a contiguous block of chars.

    Similarly, consider this line from the third example:

    p = malloc(10);
    

    This is also copying a location - it's copying the location of a block of 10 unintialised chars into p.

    strcpy(dest, source) copies characters from the location given by source to the location given by dest. It should be clear that if you never set p to a valid location, then strcpy(p, "hello") can't do anything sensible - in your second example, p is an essentially random location, and you then ask strcpy() to copy something to that location.

    0 讨论(0)
  • 2021-02-10 02:08

    Yes its annoying. You can use strdup to shorten it:

    char *p = strdup("hello");
    printf("p is %s \n",p);
    
    0 讨论(0)
  • 2021-02-10 02:11

    In the case where p="hello world"; (1st case at the time of this edit), p is being initialized to point to a read-only memory region which contains the string "hello world" (string literal). This read-only memory region is created at compile time.

    In the case that causes the segmentation fault (2nd case at the time of this edit), p is uninitialized and copying anything to it will produce unpredictable results because the location in memory that p is pointing to is not specified by the code.

    Before you can copy a string to p, you must specify the memory that p is pointing to.

    You can allocate this memory on the stack

    char buf[BUFSIZ] = ""; /* local variable */

    on the heap

    char *buf = malloc(BUFSIZ); /* don't forget to free */

    or in the __DATA segment.

    static char buf[BUFSIZ] = ""; /* global variable */

    You can then initialize p to point at the memory buffer.

    char *p = buf;

    This is similar in concept to initializing p to point to the string literal in read-only memory. Unlike the case where p points to the string literal, you can now copy a string to the character pointer as it does not point to read-only memory.

    Note: I intentionally created a separate buffer and initialized p to point to it to help make my point.

    0 讨论(0)
  • 2021-02-10 02:15

    There are two distinct parts to memory copying. The first is the memory occupied by the item you want to copy (which you create in your example using the malloc() function), and the second is a pointer to that block of memory (which you call p). These two entities must be set up for the destination too, before you can do a copy. In your first example that fails, you have not set up the memory block for the destination (but it has been set for the source implicitly when you declare the string hello).

    0 讨论(0)
提交回复
热议问题