Thread: Pointers to Characters... char *s

  1. #1
    People Love Me
    Join Date
    Jan 2003
    Posts
    412

    Pointers to Characters... char *s

    I never really was much for pointers and strings...so I don't really see why a declaration like

    char *s = "This is a string";

    ...works...when something like

    int *x = 5;

    ...does not. It has something to do with a pointer to a character being synonymous with an array of characters or something, right? But....a pointer is a variable that points to a memory address...how can it be perfectly legal to point to just an arbitrary string?

    Consider this code:

    Code:
    #include <iostream>
    using namespace std;
    
    char* Trunc(char* s, int max){
    //'max' is 5: so when i=5, make the current character NULL and return the string
         for(int i=0;  i<=max;  i++){
                 if(i==max){
                     s[i]='\0';
                     return s;
                 }
           }
    }
    
    int main(void){
        char *m = Trunc("This is a string...",5);
        cout << m;
        cin.get();
        return 0;
    }
    That doesn't really work as planned...in fact, it crashes the program...why is this?

  2. #2
    Tropical Coder Darryl's Avatar
    Join Date
    Mar 2005
    Location
    Cayman Islands
    Posts
    503
    because "This is a string..." is a constant literal and can't be modified;

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    I never really was much for pointers and strings...so I don't really see why a declaration like

    char *s = "This is a string";

    ...works...when something like

    int *x = 5;
    A "string literal" is something enclosed in double quotes, and whenever the compiler comes across a string literal, it slaps a '\0' character onto the end of it and stores it in memory somewhere. Then, the operator= is overloaded for type char* so that if there is a string literal on the right side, the address of the memory location is stored in the variable on the left side.

    With the statement:

    int* x = 5;

    the operator= is not overloaded the same way for type int*. For type int*, there needs to be an address on the right side.

    That doesn't really work as planned...in fact, it crashes the program...why is this?
    In this line:

    char *s = "This is a string";

    when the compiler puts the string literal in memory, the string literal's type is:

    const char*

    which reads: "pointer to a constant char". That means you cannot change the string literal at that address. The reason the type is constant is so that if you use that same string somewhere else in your program, e.g.

    char* ptr2 = "This is a string.";

    the compiler doesn't have use up more memory and store the exact same string somewhere. Instead, it just returns the address of the identical string already stored in memory. If the type wasn't constant, then if you changed the string that was assigned to one variable, it would change the string in all the other variables as well.

    If you are an astute observer, you will realize there is a type mismatch in this line:

    char *s = "This is a string";

    On the left is a pointer to a char, but on the right is the type: const char*, which is a pointer to a constant char. After that assignment, just looking at the variable type on the left, you would think you could change whatever is at the address stored in s. And, the compiler will not flag that as an error--as it normally would for other type mismatches. I have a book that says the reason the compiler lets that go is due to C legacy code. However, as you discovered, you will get a runtime crash if you try to change the string literal. So, in order to use the compiler to help you debug your code, you should declare your cstrings like this:

    const char *s = "This is a string.";

    That way you if you mistakenly try to change the string literal, you will get an error while your are compiling rather than during runtime.

    To solve the problem you encountered in your program, you need to copy each individual char in the string literal to a new char array. If you add a '\0' after the last char, then you will have a char array that is identical to the string literal--except you can change it at will. The '\0' also makes the char array a "cstring", which allows you to use all the <cstring> functions, as well as being able to output the char array using cout<<newArray.

    ...that's my story, and I'm sticking to it until further notice.
    Last edited by 7stud; 04-26-2005 at 10:20 AM.

  4. #4
    Hardware Engineer
    Join Date
    Sep 2001
    Posts
    1,398

    It's just the way the language was defined.

    It has something to do with a pointer to a character being synonymous with an array of characters or something, right?
    Right!


    There is an automatic relationship between the array name and the pointer name...

    For example:

    int SomeArray[20];
    SomeArray (without the index) is magically a pointer to the first element in the array... even though you didn't declare a pointer.

    I assume this was done so that the functions in <ctring> are easier to use.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. get keyboard and mouse events
    By ratte in forum Linux Programming
    Replies: 10
    Last Post: 11-17-2007, 05:42 PM
  2. The Interactive Animation - my first released C program
    By ulillillia in forum A Brief History of Cprogramming.com
    Replies: 48
    Last Post: 05-10-2007, 02:25 AM
  3. Obtaining source & destination IP,details of ICMP Header & each of field of it ???
    By cromologic in forum Networking/Device Communication
    Replies: 1
    Last Post: 04-29-2006, 02:49 PM
  4. Half-life SDK, where are the constants?
    By bennyandthejets in forum Game Programming
    Replies: 29
    Last Post: 08-25-2003, 11:58 AM
  5. comparing fields in a text file
    By darfader in forum C Programming
    Replies: 9
    Last Post: 08-22-2003, 08:21 AM