char pointers

Aug 7, 2009 at 7:20am
Hey all. I know about arrays and pointers, but I've never understood what's really going on here (or why it works...):

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;

int main()
{
  char * s = "Joe"; //First of all, why can I assign 3 chars to a pointer?
  cout << s << endl;

  s = "Frederick"; //Why can I change the pointer to a different number of chars? What does this even point to??
  cout << s << endl;

  return 0;
}


Output: Joe
Frederick


Could you guys explain what's going on with this? I don't really understand. Thanks!
Last edited on Aug 7, 2009 at 7:20am
Aug 7, 2009 at 8:35am
char * s = "Joe";
pointer s can point not only to char, but also to array of chars
it looks more/less like this:

s---->Joe\0

s = "Frederick";
now pointer s is pointing to another array of chars.
If we imagine that the addresses of particular chars in "Joe" were 1,2,3 (and 4 for \0), according to your code the adresses for "Frederick" will be 5,6,7,8,9,10,11,12,13 and 14 for \0

Last edited on Aug 7, 2009 at 9:02am
Aug 7, 2009 at 8:46am
I think I understand what you mean... but does that mean that the original posting is compiled the same as this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;

int main()
{
  char s1[] = "Joe";
  char s2[] = "Frederick";

  char * s = s1;
  cout << s << endl;

  s = s2;
  cout << s << endl;

  return 0;
}

thanks.
Last edited on Aug 7, 2009 at 8:47am
Aug 7, 2009 at 9:07am
yes, that code is equivalent to the previous one
Aug 7, 2009 at 9:17am
They are equivalent up to the point that you do not try to modify a string literal through a pointer.

1
2
3
4
5
6
char s1[] = "Joe";
char *s = s1;
*s = 'X'; // OK

s = "Frederick";
*s = 'X'; // Undefined behaviour 

The latter snippet is a source of undefined behaviour, probably a memory access violation.
Aug 7, 2009 at 9:34am
This confuses me though...

Why will this work:

1
2
3
4
char name[1];
cout << "Enter your name: ";
cin >> name;
cout << "Your name is " << name << endl;


and this will segfault?

1
2
3
4
5
char buffer[1];
char * name = buffer;
cout << "Enter your name ";
cin >> name;
cout << "Your name is " << name << endl;


PS. This also doesn't work, but it gets a Bus Error instead of a Segmentation Fault (though I wasn't expecting this to work):
1
2
3
4
char * name;
cout << "Enter your name ";
cin >> name;
cout << "Your name is " << name << endl;
Aug 7, 2009 at 9:48am
The first and the second should both segfault as you need an extra character for the string terminator ( '\0' ) and you will likely overflow
The third doesn't work because 'name' is not pointing to a location in memory which you own but to a random one
Aug 7, 2009 at 10:18am
I know the first one should segfault, but it doesn't, at least for me with the name "Duncan". This proves that arrays and pointers are treated differently by the compiler even when a pointer points directly to an array.. so now I'm still confused about how char pointers work.

First of all does anybody know why the first one does work? Or show how it wouldn't work in most circumstances?

And second, can anybody give a low-level explanation about how a char pointer can "point" to an array of characters? I still don't understand. I am very comfortable and familiar with how integer arrays and pointers work, but these character arrays are still puzzling to me.


Also, please use more explicit words than "equivalent".

Thanks a bunch!!
Last edited on Aug 7, 2009 at 10:23am
Aug 7, 2009 at 10:32am
I know the first one should segfault, but it doesn't, at least for me with the name "Duncan".
That may depend on your compiler, using g++4.3 I get this result: -with any input-
1
2
3
Enter your name: Bazzy
Your name is Bazzy
Segmentation fault


And second, can anybody give a low-level explanation about how a char pointer can "point" to an array of characters? I still don't understand. I am very comfortable and familiar with how integer arrays and pointers work, but these character arrays are still puzzling to me.
A pointer to char always points to a single char. An array is like a pointer but it will always point to its first element:
1
2
char array[4];
// array == &(array[0]) 
When you set a pointer equal to an array ( char *ptr = array; ) is like making it pointing to the first element of that array: char *ptr = &(array[0]);. Since arrays use contiguous memory, the pointer is like as it is pointing to the array:
ptr[1] = *(ptr+1)

You may try these useful tutorials:
http://www.cplusplus.com/doc/tutorial/arrays/
http://www.cplusplus.com/doc/tutorial/ntcs/
http://www.cplusplus.com/doc/tutorial/pointers/
Aug 7, 2009 at 11:22am
ok, after much thinking I believe I've finally made the conceptual leap to understanding these things. Haha, thanks for your help everybody!
Topic archived. No new replies allowed.