Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't I need to dereference a character pointer in C before printing it?

Tags:

c

Why does this code work? I would expect that I would need to dereference ptr, printf("%s\n", *ptr); before I could print it out, but I get a Segmentation Fault if I try to do it that way.

#include <stdio.h>

int main(int argc, char *argv[])
{
        char name[] = "Jordan";
        char *ptr = name;
        printf("%s\n", ptr);
}

Hope you guys could give me some insight.

like image 569
user1787531 Avatar asked Apr 05 '13 19:04

user1787531


People also ask

Can you always dereference a pointer?

It operates on a pointer variable, and returns an l-value equivalent to the value at the pointer address. This is called "dereferencing" the pointer. That said, we can dereference the pointer without ever accessing the value it points to.

Why do we dereference a pointer?

Dereferencing is used to access or manipulate data contained in memory location pointed to by a pointer. *(asterisk) is used with pointer variable when dereferencing the pointer variable, it refers to variable being pointed, so this is called dereferencing of pointers.

Can you printf a pointer?

You can print a pointer value using printf with the %p format specifier. To do so, you should convert the pointer to type void * first using a cast (see below for void * pointers), although on machines that don't have different representations for different pointer types, this may not be necessary.

Does Dereferencing make a copy C?

In the simple case, no.


1 Answers

When you print string we need starting address of string.

printf("%s\n", ptr);
                ^ address with %s   

it prints chars till \0 nul encounter.

Whereas to print chat int .. we need value variable:

printf("%c\n", *ptr);
               ^ * with %c print first char

Where as in scanf() a string you always need to give address:

scanf("%s", ptr);
            ^ string address

Also for int scanf() a char

scanf("%c", ptr);
            ^ read at first location char address 

Note: Scanf() need address with %c to store a scanned value in memory.

Be careful your ptr points to a constant string so you can't use in scanf.

Why Segmentation fault with following code ?

    printf("%s\n", *ptr);

When you do like this, because of %s printf interprets *ptr as an address, but it's actually not an address and if you treat it as address it points to some location that is read protected for your program(process) So it causes a segmentation fault.

Your ptr via name points to some constant string in memory ("Jordan") as in below diagram:

name 2002
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ 'J' │ 'o' │ 'r' │ 'd' │ 'a' │ 'n' │'\0' │ ........
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
  ^
  |
 ptr = name 

 ==> ptr = 2002
     *ptr = 'J'

In printf("%s\n", *ptr); the *ptr = 'J' and ASCII value of char 'J' is 74 but 74 address is not under your process control and you are trying to read from that memory location and its a memory violation and segmentation fault occurs.

If you compile you code containing printf("%s\n", *ptr); then with proper option say -Wall with GCC you will get a warning like below:

warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’

Says %s need (expects ) an address of type char* but you are putting value

notice:

printf("%s\n",   *ptr);
        ^          ^ argument-2
        argument-1 
like image 56
Grijesh Chauhan Avatar answered Sep 21 '22 15:09

Grijesh Chauhan