Take the 2-minute tour ×

I am not sure if I worded the question correctly, but here it is spelled out:

char * cp = "this is a char pointer";

The code above, based on my currently limited understanding, seems to be acceptable. However, the code below does not seem acceptable:

int * ip;  // UPDATED
*ip = 5;   // UPDATED

Rather, I must say something like:

int x;
int * ip;
ip = &x;
x = 5;

So with the character string, I can just initialize my pointer to point right at a string literal as soon as I spell it out. I don't have to identify that string literal with any other variable... but maybe this is because of the close relationship between pointers and arrays, and I actually am simultaneously identifying it with the implicit array of same name? (my attempt at partially answering my own question)

But with the integer, I cannot just point to an integer value floating in memory. I must give that integer value a variable name and point at the variable location.

I'm guessing this might have something to do with the differences of stack vs heap storage? Something I'm still a little weak on...

Any further insight would be appreciated! Thanks!

share|improve this question
I updated the part of the code about int pointers. I realized what I had before was trying to store 5 as the pointer value, rather than the value of the "pointee" which is what I intended. Though I think I already have some answers that make sense... –  The111 Dec 4 '11 at 0:07
add comment

8 Answers

up vote 6 down vote accepted

Your understanding is correct. A string literal is really an array of char, and taking its value really yields a pointer to its first element. You can do this for any literal array (but without the syntax sugar that you have char arrays).

char *s = "String";        // right side is array of char
int *x = (int []){1, 2};  // right side is array of int

Similarly, the following are both incorrect.

char *s = 'S';
int *x = 1;

Note the difference between "String" and 'S'. The former is an array of char, but the latter is just an int.

However (as was first mentioned by Keith), string literals and literal arrays (more generally called compound literals) have different storage duration. In particular, a string literal always has static storage duration; but a compound literal has automatic or static storage duration, depending if it appears in a function or not. This means that if you take a pointer to a compound literal from within a function:

  • You can read and change change it until execution goes past the end of its block, and
  • You must not access it in any way after execution goes past the end of its block. Contrary, with string literals, you can read them after that, because they have static storage.

In this respect, taking a pointer to a literal array is very similar to just declaring an array (except, for example, sizeof()):

int x[] = {1, 2};
share|improve this answer
Your fourth line should surely be int *x = 1;, should it not? –  Chris Lutz Dec 3 '11 at 23:59
char *s = "String"; is not an assignment. –  Oli Charlesworth Dec 3 '11 at 23:59
@ChrisLutz: I fixed that. –  Keith Thompson Dec 4 '11 at 0:04
I edited my OP question also... the "int *x = 1" is not quite what I was trying to do, but I think I understand now why it won't work. It seems like arrays (whether char or int) are allocated storage as soon as they are mentioned... but a single char or a single int does not get storage unless assigned to a variable. Is that accurate? Thanks! –  The111 Dec 4 '11 at 0:10
Reading through this again... I never knew string literals had static storage duration! Another question I had today was predicated on me not realizing that. Thanks again! –  The111 Dec 4 '11 at 6:36
add comment

The char[] has been explained, but I think the most important thing to remember in the int example is that:

int x;  // memory space created for an int
int *ip;  // pointer
ip = &x;  // assigning a pointer
x = 5; // assigning a value to the memory space referenced by x


int *ip; // this is a pointer - no space in memory has been allocated for an int
*ip = 5;  // hence why you can't assign a value here - there's nowhere to put it!
share|improve this answer
Ok, but why isn't space allocated for 5 just as space as allocated for "a string"? I guess because "a string" is an array, but even then why is space allocated for an array but not a single value? I think it has to do with Omri's answer above. Which even then, there is another "why" behind that why. Even if we know that compiler automatically allocated storage for string, but not for integer unless given a variable name, why does compiler act that way? I guess that is a compiler design question and probably deeper than I can handle now! –  The111 Dec 4 '11 at 0:38
Sorry, have been travelling and didn't notice this question :) Essentially, as you've worked out above, there are differences between how arrays and single int/char are allocated storage. Fundamentally though, char *s = "Some String"; is still assigning a reference to a pointer (because "Some String" is a char*), which is legal, while int *ip = 5 is trying to assign a value to a pointer, which doesn't work. You might be able to assign the reference to that 5: see here –  MattJenko Feb 9 '12 at 20:07
add comment

The simplified reason is that a string is a value that does "float in memory". The compiler actually takes the string and puts it in your executable (or library), and when you load the program into memory, the string has an address, and when you use the string you're actually getting a pointer to that address.

But for integers, the compiler doesn't automatically put the value in memory. It might do, if you tell it to explicitly (using an assignment into a variable and then taking the address of the variable). But in some cases it may choose to store it in a register, which doesn't have an address. It may also choose not to store it at all, depending on optimisation options.

share|improve this answer
This is the kind of answer I was looking for. Are there any texts you can recommend to better understand these phenomenon? Most C language texts just tell you what to do, but not why. It is interesting to understand what your computer is actually doing with your memory, in response to your C instructions. –  The111 Dec 3 '11 at 23:58
That's a very good question. It's probably why people recommend that you learn assembly language (at least a little bit). It can be very enlightening to see what the compiler does with your code. A reasonably good book (although getting pretty old) is "Expert C Programming" by Peter van der Linden. –  Omri Barel Dec 4 '11 at 0:27
Thanks Omri, I'll check that book out after I finish my second reading of K&R. :-) –  The111 Dec 4 '11 at 0:30
The comp.lang.c FAQ is an excellent resource. –  Keith Thompson Dec 4 '11 at 3:20
Thanks Keith. I noticed you mention that elsewhere and I will definitely be checking it out! –  The111 Dec 4 '11 at 6:40
add comment

Any valid non-null pointer must point to some object. That object needn't be a declared, named variable.

A string literal specifies an anonymous static array object that exists somewhere in your program's memory. In most contexts, the result of evaluating a string literal is the address of the first element of that array. So given

char *cp = "this is a char pointer";

the object that cp points to is the initial (0th) element of that anonymous array.

C99 introduces compound literals, so you can actually write something like:

int *ip = (int[]){ 5 };

though the behavior is a bit different than that of string literals. In particular, if a compound literal appears inside a function, the anonymous object's lifetime is restricted to the enclosing block. And your compiler may or may not (yet) support compound literals.

share|improve this answer
I love C99 compound literals. You can make mutable string literals: (char []){"this is a char pointer, but it is writable!"} –  Chris Lutz Dec 4 '11 at 0:00
@ChrisLutz: Yes, but if it appears inside a function, the lifetime of the array is just the enclosing block. –  Keith Thompson Dec 4 '11 at 0:02
add comment

A string literal is stored in memory as a character array. You identify an array with its starting address in C. However you cannot do

int * ip = 5;

Buy you can do (edited:)

int ip[] = {5, 6, 4};

for example.

share|improve this answer
No, you can't (try it). That's a valid initializer for an array, not for a pointer. –  Keith Thompson Dec 3 '11 at 23:55
@KeithThompson - I believe in C99 you can do int *ip = (int []){ 5, 6, 4 }; (or something), which would achieve something similar (array goes on the stack and is mutable, rather than in static storage like a string literal, but otherwise it "works"). –  Chris Lutz Dec 3 '11 at 23:58
Well I changed the answer to be more precise. Thanks. –  Furkan Kıraç Dec 4 '11 at 0:11
add comment

the compiler does not allocate memory for a string neither for an interger if you declare char* or int*.

the memory is allocated only if you specify it : char* p1 = "string"; for a const string or char* p2 = (char*)malloc(5*sizeof(char)); for a normal dynamically allocated array of char which can be modified or char p3[10]; for array of char which can be use as a string.

then you can fill p2 and p3 with the string you want : strcpy (p2 , "Hi");

you cannot not do the same with p1 : strcpy(p1 , "Hi"); will certainly crash the program.

then when you write int* ip;,int x;, p=&x; : you allocate the memory for the int with the line int x;.

yo can allocate the memory also with int *ip2 = (int*)malloc(sizeof(int)) then you have not to associate the pointer with a variable. the int can be changed with *ip2 = 3;.

share|improve this answer
add comment

In C, strings are pointers to null-terminated sequences of characters. That's why:

char * cp = "this is a char pointer";

is accepted. On the other hand, if:

int * ip = 5;

were accepted (you can force it if you insist), it would declare "ip is a pointer to an int, whose address is 5").

share|improve this answer
No, a string is a sequence of characters terminated by and including the first null character. A string is not a pointer. (Like any array expression, it's converted to a pointer to the array's first element in most, but not all, contexts.) Read section 6 of the comp.lang.c FAQ. –  Keith Thompson Dec 3 '11 at 23:59
add comment

Strings are essentially arrays of characters. Array type (e.g char[]) variables can often be referred to as pointers (char*, pointer to beginning of an array). That means string literals are of type char* and that is why you can just assign that string to a pointer. On the other hand, integer literals, like '5' are of type int, so you cannot assign it to a pointer.

share|improve this answer
No, char[] and char* are very different types. Arrays are not pointers. Pointers are not arrays. Array expressions decay to pointers in most (but not all) contexts -- which is what causes a lot of confusion. See section 6 of the comp.lang.c FAQ. –  Keith Thompson Dec 3 '11 at 23:56
Obligatory -1 for "arrays are equivalent to pointers". –  Oli Charlesworth Dec 3 '11 at 23:59
add comment

Your Answer


