2

I am new to C, and currently I am trying to understand how pointers work.

Here is one problem that confuses me:

As far as I know, before assigning a value to pointer, you should allocate certain memory for that pointer (if I am wrong, please correct me :) ), like the code below:

int main(void) {
    int i;
    int * ptr = (int *)malloc(sizeof(int));

    i = 2;
    *ptr = 5;     
    printfn("%d",*ptr); 
    free(ptr);
}

However, when declaring string in C, just like:

char *p = "Hello world"; 

without need to allocate memory.

What's the reason and how does it work? If I am missing something, kindly remind me.

Jens Mühlenhoff
  • 14,565
  • 6
  • 56
  • 113
J.L
  • 592
  • 5
  • 17
  • 35
  • 4
    You're missing what the expression *value* of an array is in the C language. It is an *address* (of the first element in the contiguous sequence). And pointers hold: *addresses*. A string literal is a read-only array of `char`. That said (1) [don't cast malloc in C programs](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc), and (2) if you're assigning a string *literal* to a pointer, use a `const` pointer. – WhozCraig Jun 13 '14 at 10:15
  • 1
    http://stackoverflow.com/questions/14004302/how-c-strings-are-allocated-in-memory?rq=1 – Mat Jun 13 '14 at 10:16
  • Oh god. Is this really a question worth +4? (hint: no.) – The Paramagnetic Croissant Jun 13 '14 at 10:27
  • `printfn`? Are you in [F#](http://msdn.microsoft.com/en-us/library/ee370571.aspx)? – ikh Jun 13 '14 at 10:28

3 Answers3

9

char *p = "Hello world";

you created a pointer and pointed it at a constant string. The compiler puts that in a part of memory that is marked as read-only.

it has no name and has static storage duration (meaning that it lives for the entire life of the program); and a variable of type pointer-to-char, called p, which is initialized with the location of the first character in that unnamed, read-only array.

Jayesh Bhoi
  • 24,694
  • 15
  • 58
  • 73
  • thanks, I understand what you said, now my question is does compiler will do the same thing with int type (like the example I mentioned)? – J.L Jun 13 '14 at 10:24
  • @Justin for single variable `int` you not need to allocate. it will allocate size (sizeof(int)) at run time on stack. For `int` array you can allocate dynamical as you already done or give fix array size. – Jayesh Bhoi Jun 13 '14 at 10:27
  • just int *ptr; *ptr = 5; is valid or invalid? I think it's invalid, *ptr does not know where should it point to (I mean address). – J.L Jun 13 '14 at 10:33
  • @Justin No not valid!!. It just pointer. Not point any memory address. it will cause you segmentation fault. – Jayesh Bhoi Jun 13 '14 at 10:37
4

"Hello world" is static data, which is compiled into your binary, just like the 2 and the 5 in your example.

char * p is defined to be a pointer to that location in your binary.

Which is also why it should be char const, as you shouldn't ever write to that location. (Your compiler should have given you a warning about this.)

DevSolar
  • 67,862
  • 21
  • 134
  • 209
3

...you should allocate certain memory for that pointer ...

No, you seems to misunderstand about pointers...

Pointer is the type which hold some type's address. Look at this example.

int a = 1;
int *p = &a;

The type of a is int, which contains integer.

The type of p is int *, which contains address of integer variables.

Let's suppose memory like this:

--------------------------------------
variables: | a          | p          |
--------------------------------------
address  : | 0x12341234 | 0x12341238 |
--------------------------------------

the & operator gets the address of operand. So, &a is equal to 0x12341234.

So the variables are initialized like this:

--------------------------------------
variables: | a          | p          |
--------------------------------------
address  : | 0x12341234 | 0x12341238 |
--------------------------------------
value    : | 1          | 0x12341234 |
--------------------------------------

Now, look this code, *p. the * operator, dereference operator, gets the value of the variables which the pointer is pointing. In this case, p contains 0x12341234 - What variables is in 0x12341234? the a! So *p is equal to 1, which a contains.


Now look this example:

#include <stdlib.h>

char c1 = '1';

int main()
{
    char c2 = '2';

    char *p1 = &c1;
    char *p2 = &c2;

    char ar[13] = "hello world!"; /* don't forget '\0' : 12 + 1. */

    char *p3 = &ar[0];
    const char *p4 = "hello world!"; /* notice the type, `const char *` */

    char *p5 = malloc(13 * sizeof(char));
}

c1 is global variables, so compiler place it on the data section of program directly. c2 is local variables of main, so it is placed on stack by main. Anyway, they're placed on memory. And p1 and p2 contains their address, so *p1 is '1' (c1) and *p2 is '2' (c2).

ar is 13-length array of char. It is placed on memory like this:

------------------------------------------------------
|'h'|'e'|'l'|'l'|'o'|' '|'w'|'o'|'r'|'l'|'d'|'!'|'\0'|
------------------------------------------------------

And &ar[0] is the address of the first element of ar, so p3 contains the address of 'h'.

Now look at p4. It's initialized by "hello world!". Your question is where it is allocated - it's just (string) constant, like 1234, 2.71 or 'a'. Constant is placed on the program directly, by compiler. Like c1, the string constant is placed on the rodata section of program directly. Contrast to data section, rodata section is read-only (Read Only DATA) because string constant is constant. (As you know, constant is read-only.) So the type of p4 is const char *.

p5 is initialized by return value of malloc, that is from dynamic allocation. In this case, malloc allocates the memory somewhere, and p5 is initialied by this.

ikh
  • 10,119
  • 1
  • 31
  • 70