What type is x in "char x[2];"?

Discussion in 'C++' started by cppaddict, Aug 30, 2004.

  1. cppaddict

    cppaddict Guest

    I thought that:

    char x[2];

    made x into a pointer-to-char.

    But how come the following code won't compile:

    int main() {
    char pbuf[2];
    pbuf[0] = 'a';
    pbuf[1] = '\0';
    std::cout << pbuf << std::endl;

    pbuf = new char[2]; //Lvalue Required ERROR
    pbuf[0] = 'b';
    pbuf[1] = '\0';
    std::cout << pbuf << std::endl;
    delete[] pbuf;

    return 0;
    }

    In contrast, the following code compiles and runs as expected:

    int main() {
    char *pbuf;
    pbuf = new char[2];
    pbuf[0] = 'a';
    pbuf[1] = '\0';
    std::cout << pbuf << std::endl;
    delete[] pbuf;

    pbuf = new char[2];
    pbuf[0] = 'b';
    pbuf[1] = '\0';
    std::cout << pbuf << std::endl;
    delete[] pbuf;

    return 0;
    }

    Why won't the first example work?

    Thanks,
    cpp
     
    cppaddict, Aug 30, 2004
    #1
    1. Advertising

  2. cppaddict

    Mike Wahler Guest

    "cppaddict" <> wrote in message
    news:...
    > I thought that:
    >
    > char x[2];
    >
    > made x into a pointer-to-char.


    No. 'x' is an array.

    An array is not a pointer.
    A pointer is not an array.

    >
    > But how come the following code won't compile:
    >


    #include <iostream> /* for std::cout */
    #include <ostream> /* for std::endl */

    > int main() {
    > char pbuf[2];
    > pbuf[0] = 'a';
    > pbuf[1] = '\0';
    > std::cout << pbuf << std::endl;
    >
    > pbuf = new char[2]; //Lvalue Required ERROR


    You Can't Do That. Arrays cannot be assigned to like that.
    Only each individual element can be assigned.

    Again, an array is not a pointer. A pointer is not an array.
    I thought you'd been posting and reading here long enough
    to know that by now. :)

    > pbuf[0] = 'b';
    > pbuf[1] = '\0';
    > std::cout << pbuf << std::endl;
    > delete[] pbuf;
    >
    > return 0;
    > }
    >
    > In contrast, the following code compiles and runs as expected:


    Yes, because 'pbuf' is a pointer, to which you can assign
    a value.

    #include <iostream> /* for std::cout */
    #include <ostream> /* for std::endl */

    > int main() {
    > char *pbuf;
    > pbuf = new char[2];
    > pbuf[0] = 'a';
    > pbuf[1] = '\0';
    > std::cout << pbuf << std::endl;
    > delete[] pbuf;
    >
    > pbuf = new char[2];
    > pbuf[0] = 'b';
    > pbuf[1] = '\0';
    > std::cout << pbuf << std::endl;
    > delete[] pbuf;
    >
    > return 0;
    > }
    >
    > Why won't the first example work?


    Because an array is not a pointer. Because arrays cannot
    be assigned to. Because the return type of operator 'new'
    is a pointer, so even if you could assign to an array,
    it's the wrong type (it's not a pointer).

    -Mike
     
    Mike Wahler, Aug 30, 2004
    #2
    1. Advertising

  3. cppaddict wrote:
    > I thought that:
    >
    > char x[2];
    >
    > made x into a pointer-to-char.
    > ...


    No, 'x' here is of type 'char[2]'. The rest follows.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Aug 30, 2004
    #3
  4. cppaddict

    cppaddict Guest


    >#include <iostream> /* for std::cout */
    >#include <ostream> /* for std::endl */


    Already had those. Just weren't in the post...

    >Again, an array is not a pointer. A pointer is not an array.
    >I thought you'd been posting and reading here long enough
    >to know that by now. :)


    Indeed. I should have. I'm a little embarrassed, but my confusion
    comes from some semi-legitimate sources. First, the fact that you can
    do pointer arithmetic with arrays. For example, the following prints
    b:

    int main() {
    char pbuf[2];
    pbuf[0] = 'a';
    pbuf[1] = 'b';
    pbuf[2] = '\0';
    std::cout << *(pbuf+1);

    return 0;
    }

    This makes it seem like a pointer. Also, I've been working with the
    Windows API, which often makes pointers and arrays seem
    interchangeable. For example, consider this code for retrieving a
    line from a Rich Edit control:

    char pbuf[100];
    pbuf[99] = '\0';
    pbuf[0] = 99 //specifies max number of characters to retrieve;
    SendMessage(hwndRichEdit,EM_GETLINE,0,(LPARAM)pbuf);
    std::cout << "Line 1: " << pbuf << std::endl;

    which works. The LPARAM is of type pointer I'm pretty sure. The docs
    are here:

    http://msdn.microsoft.com/library/d...lreference/editcontrolmessages/em_getline.asp

    Can you explain why the above two things work even though pointers and
    arrays of different types?

    Thanks,
    cpp
     
    cppaddict, Aug 30, 2004
    #4
  5. "cppaddict" <> wrote in message
    news:eek:...
    >
    >>#include <iostream> /* for std::cout */
    >>#include <ostream> /* for std::endl */

    >
    > Already had those. Just weren't in the post...
    >
    >>Again, an array is not a pointer. A pointer is not an array.
    >>I thought you'd been posting and reading here long enough
    >>to know that by now. :)

    >
    > Indeed. I should have. I'm a little embarrassed, but my confusion
    > comes from some semi-legitimate sources. First, the fact that you can
    > do pointer arithmetic with arrays. For example, the following prints
    > b:
    >
    > int main() {
    > char pbuf[2];
    > pbuf[0] = 'a';
    > pbuf[1] = 'b';
    > pbuf[2] = '\0';
    > std::cout << *(pbuf+1);
    >
    > return 0;
    > }
    >
    > This makes it seem like a pointer. Also, I've been working with the
    > Windows API, which often makes pointers and arrays seem
    > interchangeable. For example, consider this code for retrieving a
    > line from a Rich Edit control:
    >
    > char pbuf[100];
    > pbuf[99] = '\0';
    > pbuf[0] = 99 //specifies max number of characters to retrieve;
    > SendMessage(hwndRichEdit,EM_GETLINE,0,(LPARAM)pbuf);
    > std::cout << "Line 1: " << pbuf << std::endl;
    >
    > which works. The LPARAM is of type pointer I'm pretty sure. The docs
    > are here:
    >
    > http://msdn.microsoft.com/library/d...lreference/editcontrolmessages/em_getline.asp
    >
    > Can you explain why the above two things work even though pointers and
    > arrays of different types?
    >


    It works because when an array is passed to a function it decays to a
    pointer to its first element.

    > Thanks,
    > cpp
    >


    / WP
     
    William Payne, Aug 30, 2004
    #5
  6. cppaddict

    Sohail Guest

    char x[2];
    means x is a charachter array of size 2 .
    x is kind of a constant pointer and hence you cannot dynamically
    point x to some other memory location.
    whereas char *px; means px is a pointer to charachter, since it is not
    constant you can dynamically make it point to any new memory location
    allocated with new char[]

    Hope this helps.

    Sohail
     
    Sohail, Aug 30, 2004
    #6
  7. cppaddict

    Jerry Coffin Guest

    cppaddict <> wrote in message news:<>...
    > I thought that:
    >
    > char x[2];
    >
    > made x into a pointer-to-char.


    No -- this defines x as an array of char.

    > But how come the following code won't compile:
    >
    > int main() {
    > char pbuf[2];
    > pbuf[0] = 'a';
    > pbuf[1] = '\0';
    > std::cout << pbuf << std::endl;
    >
    > pbuf = new char[2]; //Lvalue Required ERROR


    Because an array isn't a (modifiable) lvalue.

    [ ... ]

    > Why won't the first example work?


    Your code is ill-formed because your understanding about x was
    incorrect.

    As you've defined it above, x is an array. If you were to pass x as a
    parameter to a function, then what would be passed would be a pointer
    to the beginning of the array, but here you're not passing it as a
    parameter. As it stands right now, you're trying to assign to x which
    is an array, and assigning to an array simply isn't allowed.

    Note that as a parameter, what you get is a pointer even if you use
    array-style notation in the function declaration/definition. For
    example:

    void f(char x[2]) {
    // This is well-formed code. The '2' above is entirely ignored
    // so we can assign a pointer to a larger array, such as:
    x = new char[20];
    }

    You can argue (and I'd agree) that this is usually a bad idea, but the
    compiler won't do a thing to stop it. If you're feeling particularly
    ornery, you can even do something like:

    void f(char x[2]);
    void f(char *x) { }

    and get away with it -- at least with the compiler. Of course, if any
    of your co-workers find out, it's your problem, not mine! :)

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Aug 30, 2004
    #7
  8. char pbuf[2];
    is an array. An array is NOT same as a pointer.
    It means the address the array points to is a constant, it cannot be changed.
    Hence
    pbuf = new char[2];
    is WRONG

    In this
    char *pbuf;
    pbuf is NOT an array, it is a pointer so its address can be changed.
    Hence
    pbuf = new char[2];
    works fine.

    hth
    david michell
     
    David Michell, Aug 30, 2004
    #8
  9. Le lundi 30 août 2004 à 06:03, cppaddict a écrit dans comp.lang.c++ :

    > char pbuf[2];
    > pbuf[0] = 'a';
    > pbuf[1] = 'b';
    > pbuf[2] = '\0';


    Now, wait a minute! You declare an array of two, then assign three
    elements...

    --
    ___________ 2004-08-30 11:00:46
    _/ _ \_`_`_`_) Serge PACCALIN -- sp ad mailclub.net
    \ \_L_) Il faut donc que les hommes commencent
    -'(__) par n'être pas fanatiques pour mériter
    _/___(_) la tolérance. -- Voltaire, 1763
     
    Serge Paccalin, Aug 30, 2004
    #9
  10. cppaddict wrote:
    >
    >
    > Can you explain why the above two things work even though pointers and
    > arrays of different types?


    You need to distinguish between what things *are* and how things are
    *used*

    If the name of an array is used without an indexing operation (*), then the
    name of the array decays into a pointer to its first element. But note:
    The name is still not a pointer, it is just used as if it were one.

    Heck. Even array indexing is defined in terms of pointer operations:

    char b[10];

    b[5] is identical to *(b+5) by definition


    (*) with sizeof beeing one exception that comes to my mind immediatly

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Aug 30, 2004
    #10
  11. cppaddict

    Daniel T. Guest

    In article <>,
    cppaddict <> wrote:

    > I thought that:
    >
    > char x[2];
    >
    > made x into a pointer-to-char.


    It's more like a const-pointer-to-char. Note, I'm not saying it *is*
    such a beast, but its very much *like* one.
     
    Daniel T., Aug 30, 2004
    #11
  12. On Mon, 30 Aug 2004 07:28:42 +0200
    "William Payne" <> wrote:

    > > Can you explain why the above two things work even though pointers
    > > and arrays of different types?
    > >

    >
    > It works because when an array is passed to a function it decays to a
    > pointer to its first element.


    Which also makes sizeof useless within the function. If you were to know
    the array's elements, you'd need to add a parameter index:

    foo(array,sizeof array/sizeof array[0]);

    best regards
    Moritz Beller
    --
    web http://www.4momo.de
    mail momo dot beller at t-online dot de
    gpgkey http://gpg.notlong.com
     
    Moritz Beller, Aug 30, 2004
    #12
  13. cppaddict wrote:
    > Can you explain why the above two things work even though pointers and
    > arrays of different types?
    >
    > Thanks,
    > cpp
    >


    Now would be a good time to become familiar with
    Chris Torek's, "The Rule". Search the Web for
    "Chris Torek The Rule". He explains in depth
    the difference between an array and a pointer.


    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c -faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.comeaucomputing.com/learn/faq/
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
     
    Thomas Matthews, Aug 30, 2004
    #13
  14. cppaddict

    Mike Wahler Guest

    Mike Wahler, Aug 30, 2004
    #14
  15. cppaddict

    Default User Guest

    Karl Heinz Buchegger wrote:
    >
    > cppaddict wrote:
    > >
    > >
    > > Can you explain why the above two things work even though pointers and
    > > arrays of different types?

    >
    > You need to distinguish between what things *are* and how things are
    > *used*
    >
    > If the name of an array is used without an indexing operation (*), then the
    > name of the array decays into a pointer to its first element. But note:
    > The name is still not a pointer, it is just used as if it were one.
    >
    > Heck. Even array indexing is defined in terms of pointer operations:
    >
    > char b[10];
    >
    > b[5] is identical to *(b+5) by definition
    >
    > (*) with sizeof beeing one exception that comes to my mind immediatly



    Also the address-of operator (&).

    That means that &b is NOT char** but is a pointer to array 2 of char.




    Brian Rodenborn
     
    Default User, Aug 30, 2004
    #15
  16. cppaddict

    cppaddict Guest


    >Now would be a good time to become familiar with
    >Chris Torek's, "The Rule". Search the Web for
    >"Chris Torek The Rule". He explains in depth
    >the difference between an array and a pointer.


    Thanks for the reference.... very interesting.

    cpp
     
    cppaddict, Aug 30, 2004
    #16
  17. cppaddict

    Old Wolf Guest

    cppaddict <> wrote:
    >
    > the following prints b:
    >
    > int main() {
    > char pbuf[2];


    I guess you mean: char pbuf[3];

    > pbuf[0] = 'a';
    > pbuf[1] = 'b';
    > pbuf[2] = '\0';
    > std::cout << *(pbuf+1);
    >
    > return 0;
    > }
    >
    > This makes it seem like a pointer.


    When you use the name of an array in any expression other than
    those listed below, it is as if you had written: &x[0].
    The exceptions (I think..): sizeof x, &x, x++, ++x, --x, x--,
    or where x is on the left-hand side of an assignment (=, +=, -=, etc.)
     
    Old Wolf, Aug 31, 2004
    #17
    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. Toby
    Replies:
    3
    Views:
    3,135
    Mike Treseler
    Sep 7, 2005
  2. heyo
    Replies:
    3
    Views:
    958
    Dan Pop
    Apr 1, 2004
  3. pete
    Replies:
    4
    Views:
    829
    Dan Pop
    Apr 2, 2004
  4. Yevgen Muntyan

    #define ALLOCIT(Type) ((Type*) malloc (sizeof (Type)))

    Yevgen Muntyan, Feb 9, 2007, in forum: C Programming
    Replies:
    10
    Views:
    944
    Yevgen Muntyan
    Feb 13, 2007
  5. kj
    Replies:
    5
    Views:
    429
Loading...

Share This Page