Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does a pointer initialise to?

One thing that always confused me , the character pointer. It's after long four years that I am again lingering into c.

Take for example the mentioned case .Why does char pointer behave in this way ? How can we directly address the contents of the pointee when it points to nothing or is it like char pointer stores stuffs other than addresses !

#include <stdio.h>
#include <stdlib.h>

int main()
{ 
char* charPtr="I cant understand why";
int* intPtr=60;


printf("%d\n", intPtr); //displays 60
printf("%p\n", intPtr); // displays the hex value of 60

printf("%s\n", charPtr); // displays the wh0le string
printf("%p\n", charPtr); // displays the start address of the string
return 0;

}

Next the int pointer , How can it accept the value 60 and where does it get stored ?

leaving aside the char pointer and malloc ,I thought the basic idea of the pointer was to get an address to point to !

why does these cases

 *intptr = 60 ; // should be setting the pointee's value to 60
  intptr = 60 ;  // sets the address

throw compilation error while

  int* intPtr=60;

sneaked in without getting an address ( or is 60 taken as the address ,if so why is this not acceptable not in the former case)of the the pointee !

I guess I am missing something here but hey ! Guess what ? they told me to search in SO !

EDIT : Giving the address pointed to by the char pointer to an int pointer also throws in no error !

int8_t* intPtr= (int8_t*)0x80485c8 ; // works without casting too ! I guess addresses are acceptable.

Dereferencing it will give a value equivalent to the first I of the string .Is this a good practise or there exists any other explanation to this leaving out thier byte bit size allocation such as an int can hold a char and so.. ?

As hmjd pointed out the ' initialisation syntax ' is the problem ! I have no problem writing my own code but trouble arises when modifying someone's code !

like image 536
Borrito Avatar asked Aug 29 '12 09:08

Borrito


3 Answers

How can we directly address the contents of the pointee when it points to nothing or is it like char pointer stores stuffs other than addresses !

I think the confusion is the initialisation syntax. This:

char* charPtr="I cant understand why";

does not dereference charPtr. It is equivalent to:

char* charPtr;
charPtr = "I cant understand why";

Both code snippets store the address of the string literal "I cant understand why" to the charPtr. There is no dereferencing of a pointer that points to nothing occurring. A pointer variable, of any type, can store an address only.

This:

int* intPtr=60;

stores an address of 60 in intPtr: no int assignment or deferencing is occuring. No int variable exists at this point. The compiler should have emitted a warning at this line. Any attempt to deference intPtr will most likely cause a crash.

like image 107
hmjd Avatar answered Nov 09 '22 02:11

hmjd


In C, a string literal like "I can't understand why" is stored as an array of char such that the memory is available over the lifetime of the program (all addresses are pulled out of thin air and are not meant to represent any specific platform or architecture):

Item        Address        0x00  0x01  0x02  0x03
-----       -------        ----  ----  ----  ----
"I..."      0x00080000      'I'   ' '   'c'   'a'
            0x00008004      'n'   '''   't'   ' '
            0x00008008      'u'   'n'   'd'   'e'
            0x0000800C      'r'   's'   't'   'a' 
            0x00008010      'n'   'd'   ' '   'w' 
            0x00008014      'h'   'y'  0x00  0x??

The string literal is also an array expression, and in most contexts an expression of type "N-element array of T" will be converted to type "pointer to T", and its value will be the address of the first element of the array (the exceptions are when the array expression is an operand of the sizeof or unary & operators, or is a string literal being used to initialize an array in a declaration).

So when you write

char* charPtr = "I can't understand why";

you're copying the address of the string literal to charPtr:

Item        Address        0x00  0x01  0x02  0x03
----        -------        ----  ----  ----  ----
charPtr     0xffbe4000     0x00  0x08  0x00  0x00

Note that if the declaration had been

char str[] = "I can't understand why";

str would have been allocated as an array of char long enough to hold the string, and the contents of the string would have been copied to it:

Item        Address        0x00  0x01  0x02  0x03
-----       -------        ----  ----  ----  ----
str         0xffbe4000      'I'   ' '   'c'   'a'
            0xffbe4004      'n'   '''   't'   ' '
            0xffbe4008      'u'   'n'   'd'   'e'
            0xffbe400C      'r'   's'   't'   'a' 
            0xffbe4010      'n'   'd'   ' '   'w' 
            0xffbe4014      'h'   'y'  0x00  0x??

When you write

int* intPtr = 60;

you're initializing the pointer value with 60, not setting it to point to an anonymous integer with the value 60:

Item        Address        0x00  0x01  0x02  0x03
----        -------        ----  ----  ----  ----
intPtr      0xffbe4004     0x00  0x00  0x00  0x3C

Address 60 is most likely not a valid address, so attempting to dereference intPtr would most likely lead to undefined behavior.

Had you written something like

int x = 60;
int *intPtr = &x;

then you'd have a situation like this:

Item        Address        0x00  0x01  0x02  0x03
----        -------        ----  ----  ----  ----
x           0xffbe4004     0x00  0x00  0x00  0x3C
intPtr      0xffbe4008     0xff  0xbe  0x40  0x04

In this case, the value of intPtr is the address of x.

Finally, note that initialization and assignment are not the same thing.

T *x = value;

does not dereference x and assign value to the result; it assigns value directly to x. The type of value is treated as T *. Note that you should be getting warnings on

int *intPtr = 60;

along the lines of "making pointer from integer without cast".

like image 32
John Bode Avatar answered Nov 09 '22 02:11

John Bode


When you write :

 char* charPtr = "I can't understand why";

This means that the base address of the string "I can't understand why" is being assigned to

charPtr because the string literal also is a pointer to that string.

It can be viewed as :

the concept of string stored in an char array

This means that , in charPtr the base address of the whole string is being stored .Now this is what you have done in your code .

 char *charPtr="i cant understand why";

Adding to that , if you print statements like :

printf("%c","i cant understand why"[0]);//prints i
printf("%c","i cant understand why"[2]);//prints c

These two printf's justify my concepts that the string "i cant understand why" is itself a pointer to the char array in which the string is being stored.

like image 39
kTiwari Avatar answered Nov 09 '22 00:11

kTiwari