C: differences between char pointer and array

This question already has an answer here:

  • Why do I get a segmentation fault when writing to a string initialized with “char *s” but not “char s[]”? 16 answers

  • True, but it's a subtle difference. Essentially, the former:

    char amessage[] = "now is the time";
    

    Defines an array whose members live in the current scope's stack space, whereas:

    char *pmessage = "now is the time";
    

    Defines a pointer that lives in the current scope's stack space, but that references memory elsewhere (in this one, "now is the time" is stored elsewhere in memory, commonly a string table).

    Also, note that because the data belonging to the second definition (the explicit pointer) is not stored in the current scope's stack space, it is unspecified exactly where it will be stored and should not be modified.

    Edit: As pointed out by Mark, GMan, and Pavel, there is also a difference when the address-of operator is used on either of these variables. For instance, &pmessage returns a pointer of type char**, or a pointer to a pointer to chars, whereas &amessage returns a pointer of type char(*)[16], or a pointer to an array of 16 chars (which, like a char**, needs to be dereferenced twice as litb points out).


    Here's a hypothetical memory map, showing the results of the two declarations:

                    0x00  0x01  0x02  0x03  0x04  0x05  0x06  0x07
        0x00008000:  'n'   'o'   'w'   ' '   'i'   's'   ' '   't'
        0x00008008:  'h'   'e'   ' '   't'   'i'   'm'   'e'  ''
            ...
    amessage:
        0x00500000:  'n'   'o'   'w'   ' '   'i'   's'   ' '   't'
        0x00500008:  'h'   'e'   ' '   't'   'i'   'm'   'e'  ''
    pmessage:
        0x00500010:  0x00  0x00  0x80  0x00
    

    The string literal "now is the time" is stored as a 16-element array of char at memory address 0x00008000. This memory may not be writable; it's best to assume that it's not. You should never attempt to modify the contents of a string literal.

    The declaration

    char amessage[] = "now is the time";
    

    allocates a 16-element array of char at memory address 0x00500000 and copies the contents of the string literal to it. This memory is writable; you can change the contents of amessage to your heart's content:

    strcpy(amessage, "the time is now");
    

    The declaration

    char *pmessage = "now is the time";
    

    allocates a single pointer to char at memory address 0x00500010 and copies the address of the string literal to it.

    Since pmessage points to the string literal, it should not be used as an argument to functions that need to modify the string contents:

    strcpy(amessage, pmessage); /* OKAY */
    strcpy(pmessage, amessage); /* NOT OKAY */
    strtok(amessage, " ");      /* OKAY */
    strtok(pmessage, " ");      /* NOT OKAY */
    scanf("%15s", amessage);      /* OKAY */
    scanf("%15s", pmessage);      /* NOT OKAY */
    

    and so on. If you changed pmessage to point to amessage:

    pmessage = amessage;
    

    then it can be used everywhere amessage can be used.


    An array contains the elements. A pointer points to them.

    The first is a short form of saying

    char amessage[16];
    amessage[0] = 'n';
    amessage[1] = 'o';
    ...
    amessage[15] = '';
    

    That is, it is an array that contains all the characters. The special initialization initializes it for you, and determines it size automatically. The array elements are modifiable - you may overwrite characters in it.

    The second form is a pointer, that just points to the characters. It stores the characters not directly. Since the array is a string literal, you cannot take the pointer and write to where it points

    char *pmessage = "now is the time";
    *pmessage = 'p'; /* undefined behavior! */
    

    This code would probably crash on your box. But it may do anything it likes, because its behavior is undefined.

    链接地址: http://www.djcxy.com/p/72142.html

    上一篇: 在子进程中运行的程序不会循环

    下一篇: C:char指针和数组之间的区别