1

Belows are simple code to find what the pointer to array is.

#include <stdio.h>
typedef unsigned short int Ushort;

void InputYear(char (*name), Ushort *year);

int main(int argc, const char * argv[]) {
    Ushort year;
    char name[11] ;    

    InputYear(name, &year);

    printf("MY name is %s", message);
    printf("%d", year);
}

void InputYear(char (*name), Ushort *year){
    printf("please enter your name and year");
    scanf("%s %hd" ,name, year);
}

But question is, why it doesn't work if i change char name[11] --> char *name ?

The error is "segmentation fault : 11".

I learned that the name of array is also a pointer that indicates the address of first array value. In this respect, I think that char name[11] and char *name are same.

Or is there anything that I didn't know about it?

and Extra Question :

int a = 1;
int* b = &a;
printf("%s", *b);

it works. The point is that second argument of printf is the value itself, not address. but,

char hi[11] = "message";
printf("%s", hi);

in this case, second argument of printf is address itself, not value like above. What is it?? why does it happen?

Thanks you so much!

M.M
  • 138,810
  • 21
  • 208
  • 365
Chois
  • 75
  • 1
  • 2
  • 7
  • 1
    The fact that `printf("%s", *b);` works is a moot point because it's undefined behavior. As far as the first question, `char name[11]` automatically allocates space for 11 `char`s, whereas `char *name` just declares a pointer - it doesn't actually point to anything. – Drew McGowen Jan 14 '15 at 00:23
  • possible duplicate of [Is it possible to convert char\[\] to char\* in C?](http://stackoverflow.com/questions/9627962/is-it-possible-to-convert-char-to-char-in-c) – Timothy Jones Jan 14 '15 at 00:44
  • `printf("%s", *b)` doesn't "work" , maybe you meant `%d` – M.M Jan 14 '15 at 01:30
  • Try reading the [C FAQ](http://c-faq.com/aryptr/) chapter – M.M Jan 14 '15 at 01:31

3 Answers3

7

Because

char name[11];

means create an array of 11 characters, whereas

char *name;

means, create a pointer and point with it somewhere later, you can then do this

name = malloc(11);

this will point to a block of memory of 11 chars.

When you call scanf it expects the argument to point to valid memory to write into it.

So if the pointer is not initialized, you don't know where it is pointing to, malloc gives you access to memory and returns a pointer to it, you assign that pointer to name and then name becomes writable, but not yet readable.

The contents it points to, are not yet defined so you need to initialize it's contents too, for wich you can use

scanf("%10s", name);

notice the "%10s" that way you prevent writing past the allowed memory and it's useful for both, for malloc and for the array.

Note: in scanf("%10s", name); the number should be the number of characters the array can hold -1, because you need one extra character, the terminating '\0'.

After any call to malloc there are two responsabilities that you should assume, first you must make sure that there was valid memory to point to, in the opposite case malloc will return a special value, NULL, hence a correct call to malloc would be

name = malloc(11);
if (name == NULL)
    handleThisAndDontTryToUse_name_Anywhere();

the second thing, is that the system will gain you ownership of the memory the pointer points to until you decide you can release it, for which you need to call free()

/* after you are done using the block of memory */
free(name);

In the case of

char name[11];

you will not have to worry about any of this things.

One third thing you can do, is create the array and point to it with char *name; I mean

char array[11];
char *name = array;

now name is a pointer to the first element of array and from the text of your question, I trust that you understand what this means.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • `char buff[11]; char *name = buff;` is about the only thing missing from this answer. – WhozCraig Jan 14 '15 at 00:33
  • There is also, of course, the enormous difference in where the data is actually stored in memory which you completely ignore. `char array[11]` will be on the stack while `char *name; name = malloc(sizeof(char)*20);` will be coming from the heap. – David Hoelzer Feb 15 '15 at 01:15
0
char name[11];

allocates 11 bytes of writable memory into which you can store inputs. name is treated as a constant pointer to that memory.

char *name;

allocates space for a pointer variable called name, which may be changed, but it doesn't point to anything.

char *name = "Fred";

allocates both the pointer variable and 5 bytes for the string "Fred", but in non-writable memory.

Lee Daniel Crocker
  • 12,927
  • 3
  • 29
  • 55
  • 1
    In the first case `name` is an array, not a pointer of any sort (constant or otherwise) – M.M Jan 14 '15 at 01:29
  • Array names are absolutely identical to constant pointers under the covers and at runtime. During compilation they have different types in the symbol table, but they compile down to exactly the same thing. I suppose that makes a difference to pedantic language-lawyer types, but if you truly understand what C is doing--not just at the compiler level but at the actual running code--the difference is meaningless. – Lee Daniel Crocker Jan 14 '15 at 02:16
  • The difference is essential at all levels. You'll probably find that `char name[11];` reserves (at least) `11` bytes of stack space, but `char *const name = (whatever);` reserves `4` (plus whatever "whatever" reserves); these amounts are different. Also, type distinctions persist at runtime, for example `int x; scanf("%d\n, &x); char name[x]; printf("%d\n", sizeof name);`. If `name` had boiled down to a constant pointer at some stage then `sizeof name` would give you the size of a pointer, but it doesn't. The type system is crucial in C, it's not just an annoying detail. – M.M Jan 14 '15 at 02:24
  • Yes, yes, of course I understand the allocation and other compile-time difference. You are mistaken in many details of your "explanation". First, the const pointer allocates NO memory, it's a constant. Secondly, sizeof is a compile-time operator, so of course it's different. Here's what I'm saying: if you begin a C file with something like `char a[11]; char * const b = a;`, any code later in the file--any expression, any function (except compile time stuff like sizeof)--will produce bit-for-bit identical code for a and b. – Lee Daniel Crocker Jan 14 '15 at 02:38
  • `sizeof` is not a compile-time operator (in my code sample in my previous comment, its result depends on a value not known until runtime). In your latest sentence, `&b` will behave differently to `&a` . Are you aware of the conversion rule sometimes described as "decay" , and what "rvalue" means? – M.M Jan 14 '15 at 02:48
  • Again, "rvalue" applies to expressions and variables--compile time things. There's no such thing as a variable or expression at runtime. And sizeof absolutely cannot make use of any info not known at compile time--that's why you can use it in constant expressions. Also, I'm talking C here, you might be thinking C++ which is a bit different. – Lee Daniel Crocker Jan 14 '15 at 02:59
  • You're right that VLAs like your example throw a monkey wrench in my argument. That's a newfangled thing I'm not very used to--I learned C in the 80s. – Lee Daniel Crocker Jan 14 '15 at 03:04
  • It's only a monkey wrench if you think of arrays as constant pointers :) I also learned a similar way you did, however if you switch to thinking of arrays as blocks of memory (which is how they are defined in the standard, after all), and you know that using an array's name in most situations generates a pointer rvalue which points to the array's first element, then all the strangeness goes away. – M.M Jan 14 '15 at 03:16
0

why it doesn't work if i change "char name[11]" --> "char *name" ?

name is pointer defined on stack and is initialized with a junk address thus it is pointing to a random location and depending on where it is pointing you may or may not get a segmentation fault. Even if you do not get a segmentation fault, the code will still be considered defective.

Edit:

What is difference between pointer to array and just pointer?

You probably mean what is the diff between an array and a pointer. If that's the case then, array's name is a constant pointer and a pointer is a non-constant pointer.

RcnRcf
  • 356
  • 1
  • 8