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

C

cppaddict

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
 
M

Mike Wahler

cppaddict said:
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 said:
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 said:
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
 
C

cppaddict

#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
 
W

William Payne

cppaddict said:
#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
 
S

Sohail

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
 
J

Jerry Coffin

cppaddict said:
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! :)
 
D

David Michell

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
 
S

Serge Paccalin

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
 
K

Karl Heinz Buchegger

cppaddict said:
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
 
D

Daniel T.

cppaddict said:
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.
 
M

Moritz Beller

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
 
T

Thomas Matthews

cppaddict said:
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
 
D

Default User

Karl said:
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
 
C

cppaddict

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
 
O

Old Wolf

cppaddict said:
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.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top