Thread: Question about char*

  1. #1
    Registered User wtaplin's Avatar
    Join Date
    Dec 2009
    Posts
    13

    Question about char*

    I'm a little confused about the difference between using something like:
    Code:
    char s[] = "hello"
    and
    Code:
    char *s = "hello"
    I understand that the first is an array of char, and the second is a pointer. I'm just confused on what situations to use one or the other. They seem to accomplish the same thing. Also, something like:
    Code:
    char *argv[]
    I was wondering why it seems to be a combination of the two and what that accomplishes. Thanks for any answers : )

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094

    char array vs char pointer

    First of all, I recommend you take a look at this:

    C Strings (Arrays vs. Pointers)

    It describes the exact thing you are looking for, although in a course designed to teach C++. However, the part you are interested in is readable for someone with no experience in C++.

    In short when you say:

    Code:
    char name[10] = "hello";
    - you are allocating memory on the STACK for a string of 10 characters (including the string termination character \0) out of which only 6 characters are used ('h','e','l','l','o','\0')

    Code:
    char name[] = "hello";
    - you are allocating memory on the STACK for a string which is IMPLICITLY as long as the string you are assigning to it (i.e. 6 characters (hello + \0)

    Code:
    char *name;
    - you are declaring a pointer to a string which can be allocated on the HEAP. For example, a ten character string can be allocated on the HEAP using the name pointer as such:
    Code:
    name = (char*)(malloc (sizeof(char) * 10));
    If you are not familiar with the difference between STACK and HEAP memory you should look it up. It is an important aspect of programming in general, particularly in C.

    Hope this clears things up a little.
    Last edited by claudiu; 02-26-2010 at 09:48 PM.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Code:
    char *s = "hello"
    is a string literal. It's like a "even stronger" const and cannot be changed -- I think the standard forces an error on changing a literal.
    Last edited by MK27; 02-26-2010 at 09:59 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User wtaplin's Avatar
    Join Date
    Dec 2009
    Posts
    13
    Ahh ok, I think I'm starting to grasp the concept. The book I'm going through hasn't introduced stack and heap memory yet, but now that I've looked it up it's starting to come together. At first glance it seemed the author was randomly choosing string declarations, I can see there's a method now. Thanks guys!

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by claudiu View Post
    Code:
    char *name;
    - you are declaring a pointer to a string which can be allocated on the HEAP. For example, a ten character string can be allocated on the HEAP using the name pointer as such:
    Code:
    name = (char*)(malloc (sizeof(char) * 10));
    That should be
    Code:
    name = new char[10];
    And later
    [code]delete [] name;
    Avoid C in the C++ forum and vice versa.

    Quote Originally Posted by MK27 View Post
    Code:
    char *s = "hello"
    is a string literal. It's like a "even stronger" const and cannot be changed -- I think the standard forces an error on changing a literal.
    I am pretty sure it doesn't. It's implementation defined or even undefined from what I understand.
    Regardless, on Windows and Linux, string literals are read only and thus shouldn't be changed or you WILL get an error. At runtime.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by MK27 View Post
    Code:
    char *s = "hello"
    is a string literal. It's like a "even stronger" const and cannot be changed -- I think the standard forces an error on changing a literal.
    Not quite. The string literal is actually const. The "char *s = "hello";" usage is a hangover from old pre-standard versions of C (which did not support the const keyword) and allows a non-const pointer to point at the (first character of) a string literal. Any attempt to change the contents of that string literal (eg s[0] = 'b'; ) gives undefined behaviour. No error is required but a common observed effect is a run-time error.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User wtaplin's Avatar
    Join Date
    Dec 2009
    Posts
    13
    it's comin' togehter I think. char s[] = "Hello"; -- declares a string array that only leaves enough space for "Hello" and a null. char s[10] = "Hello"; -- declares a string array that has enough space for "Hello", a null character, and 4 additional bytes. char *s = "Hello"; -- declares a string that, once initialized to "Hello", cannot be changed. One thing that was throwing me off was the use of something like char *s in function arguments, but now I see it's there because it's telling the function to expect an address of char type and not the actual char.

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by wtaplin View Post
    char *s = "Hello"; -- declares a string that, once initialized to "Hello", cannot be changed.
    Not quite. It actually just declares a pointer, and then initialises that pointer with a value that happens to point to the data segment of your program where the characters 'H', 'e', 'l', 'l', 'o', '\0' are stored sequenially (and cannot bechanged).
    You can verify the differences between these by using 'sizeof'.
    char name1[10] = "hello";
    int s1 = sizeof(name1); // s1 is 10
    char name2[] = "hello";
    int s2 = sizeof(name2); // s2 is 6
    char *name3 = "hello";
    int s3 = sizeof(name3); // s3 is 4 (assuming 32-bit pointers)

    About: "char *argv[]" read type declarations from right to left. This is an array (unknown length), of pointers to char. Each one of those pointers can point to any number of characters it likes. the array of pointers is as long as argc says it is.


    Something that you may also find interesting is that in the case of jsut declaring a pointer, where the actual characters live in the data segment, the compiler is free to overlap and reuse portions of the data segment because it can assume that it is never modified. E.g. if your code contained pointers to the strings: "world", "d", "hello world", and "ld", even if some of those appeared numerous times, then the data segment could get away with just storing:
    'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0',
    You'll notice that all the shorter strings appear within this data, followed by the nul-character, and pointers to those strings can simply point to the appropriate characters inside this data. The string "hello" would need to be stored separately because it is followed by a '\0' whereas in the above is followed by a space.
    Last edited by iMalc; 02-27-2010 at 03:37 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    Registered User wtaplin's Avatar
    Join Date
    Dec 2009
    Posts
    13
    Quote Originally Posted by iMalc View Post
    Not quite. It actually just declares a pointer, and then initialises that pointer with a value that happens to point to the data segment of your program where the characters 'H', 'e', 'l', 'l', 'o', '\0' are stored sequenially (and cannot bechanged).
    You can verify the differences between these by using 'sizeof'.
    char name1[10] = "hello";
    int s1 = sizeof(name1); // s1 is 10
    char name2[] = "hello";
    int s2 = sizeof(name2); // s2 is 6
    char *name3 = "hello";
    int s3 = sizeof(name3); // s3 is 4 (assuming 32-bit pointers)

    About: "char *argv[]" read type declarations from right to left. This is an array (unknown length), of pointers to char. Each one of those pointers can point to any number of characters it likes. the array of pointers is as long as argc says it is.


    Something that you may also find interesting is that in the case of jsut declaring a pointer, where the actual characters live in the data segment, the compiler is free to overlap and reuse portions of the data segment because it can assume that it is never modified. E.g. if your code contained pointers to the strings: "world", "d", "hello world", and "ld", even if some of those appeared numerous times, then the data segment could get away with just storing:
    'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0',
    You'll notice that all the shorter strings appear within this data, followed by the nul-character, and pointers to those strings can simply point to the appropriate characters inside this data. The string "hello" would need to be stored separately because it is followed by a '\0' whereas in the above is followed by a space.
    Gettin' clearer now. Essentially, using char *s = "hello" puts "hello\0" out there in the computer's memory with 's' providing a way to find it and refer to it. The right to left tip really simplifies things too. Very interesting how the compiler can recognize and store data more efficiently : ) Thank you to everyone who gave me an answer. I apologize if I'm beating this question to death, it helps me get it straight in my head lol.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Alice....
    By Lurker in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 06-20-2005, 02:51 PM
  2. Debugging question
    By o_0 in forum C Programming
    Replies: 9
    Last Post: 10-10-2004, 05:51 PM
  3. Question about pointers #2
    By maxhavoc in forum C++ Programming
    Replies: 28
    Last Post: 06-21-2004, 12:52 PM
  4. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  5. Question, question!
    By oskilian in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 12-24-2001, 01:47 AM