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.

4
  • 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, and (2) if you're assigning a string literal to a pointer, use a const pointer. Commented Jun 13, 2014 at 10:15
  • 1
    stackoverflow.com/questions/14004302/… Commented Jun 13, 2014 at 10:16
  • Oh god. Is this really a question worth +4? (hint: no.) Commented Jun 13, 2014 at 10:27
  • printfn? Are you in F#? Commented Jun 13, 2014 at 10:28

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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)?
@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.
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).
@Justin No not valid!!. It just pointer. Not point any memory address. it will cause you segmentation fault.
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.)

Comments

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.