2

I have only recently started learning C. I was going through the concept of arrays and pointers, when I came across a stumbling block in my understanding of it.

Consider this code -

#include<stdio.h>

int main()

 {

 char string[]="Hello";
 char *ptr;

 ptr=string;

 puts(*ptr);

 return(0);

 }

It compiles, but runs into segmentation fault on execution.

The warning that I get is:

type error in argument 1 to `puts'; found 'char' expected 'pointer to char'

Now *ptr does return a character "H" and my initial impression was that it would just accept a char as an input.

Later, I came to understand that puts() expects a pointer to a character array as it's input, but my question is when I pass something like this - puts("H"), isn't that the same thing as puts(*ptr), given that *ptr does contain the character "H".

hmjd
  • 120,187
  • 20
  • 207
  • 252
user1720897
  • 1,216
  • 3
  • 12
  • 27
  • The warning pretty much explains the problem. you are passing a single char to a function that expects a pointer to a char. – Richard Chambers Oct 05 '12 at 16:02
  • 2
    In C, a char is not the same as a string of length 1. It's better to think of a char as a small number. – ams Oct 05 '12 at 16:08

6 Answers6

3

"H" is a string literal that consists of 2 bytes 'H' and '\0'. Whenever you have "H" in your code, a pointer to the memory region with 2 bytes is meant. *ptr simply returns a single char variable.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Maksim Skurydzin
  • 10,301
  • 8
  • 40
  • 53
2

By doing puts(*str), you're dereferencing the str variable. This would then try and use the 'H' character as a memory address (since that's what str) points to, then segfault since it will be an invalid pointer (since it will probably fall outside your process' memory). This is because the puts function accepts a pointer as an argument.

What you really want is puts(str).

As an aside, the latter example puts("h") populates the string table with "h" at compile time and replaces the definition there with an implicit pointer.

slugonamission
  • 9,562
  • 1
  • 34
  • 41
  • How did you come up with the concept that taking the address of 'H' would "fall in your BIOS' memory region"? There is quite some confusion in this answer (and no, giving a string literal isn't an extension but plain C). – DevSolar Oct 05 '12 at 16:03
  • @slugonamission: Also, DevSolar is right, you're just assuming that it would fall in your BIOS memory region. It's not actually right and I'd remove that if I was you. :) – netcoder Oct 05 '12 at 16:06
  • @netcoder - it came from the fact that by dereferencing `str`, you will get the value it points to, in this case, 'H', or rather, 0x48, which I _think_ it always mapped to your BIOS' storage. – slugonamission Oct 05 '12 at 16:10
  • At least on x86. Of course, it's wrong on basically any other platform, so I've removed that too :P – slugonamission Oct 05 '12 at 16:11
  • Thank You for talking about the string table and implicit pointer. I was confused why in puts("H"), "H" would mean pointer to a character array. Also the segmentation fault makes sense now. – user1720897 Oct 05 '12 at 16:58
  • It's still wrong. 'H' is simply an integer value, residing in the data section of your binary. – DevSolar Oct 06 '12 at 07:48
  • Yes. The dereference returns 'H'. That 'H' is then implicitly cast into a pointer since `puts` requires a `char*` argument, hence, attempting to read from address 0x48. – slugonamission Oct 06 '12 at 13:02
2

The puts() function takes a pointer to a string and what you are doing is specifying a single character.

Take a look at this Lesson 9: C Strings.

So rather than doing

#include<stdio.h>

int main()

 {

 char string[]="Hello";
 char *ptr;

 ptr=string;    // store address of first character of the char array into char pointer variable ptr
                // ptr=string is same as ptr=&string[0] since string is an array and an
                // array variable name is treated like a constant pointer to the first
                // element of the array in C.
 puts(*ptr);    // get character pointed to by pointer ptr and pass to function puts
                // *ptr is the same as ptr[0] or string[0] since ptr = &string[0].
 return(0);

 }

You should instead be doing

#include<stdio.h>

int main()

 {

 char string[]="Hello";
 char *ptr;

 ptr=string;  // store address of first character of the char array into char pointer variable ptr

 puts(ptr);  // pass pointer to the string rather than first character of string.

 return(0);

 }
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
1

When ever you enter string in gets or want to display it using puts you had to actually pass the location of the pointer or the string

for example

char name[] = "Something";

if you want to print that

you have to write printf("%s",name); --> name actually stores the address of the string "something"

and by using puts if you want to display

puts(name) ----> same as here address is put in the arguments
Jamal Hussain
  • 51
  • 1
  • 7
0

No.

'H' is the character literal.

"H" is, in effect, a character array with two elements, those being 'H' and the terminating '\0' null byte.

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

puts is waiting as input a string pointer so it's waiting a memory address. but in your example you provided the content of the memory which is *ptr. the *ptr is the content of the memory with address ptr which is h

ptr is memory address

*ptr is the content of this memory

the input parameter of puts is an address type but you have provided a char type (content of the address)

the puts start the printing character by character starting by the address you give it as input until the memory which contain 0 and then it stop printing

MOHAMED
  • 41,599
  • 58
  • 163
  • 268