2

The following code works but why do I have to use 'x' instead of '&x' inside scanf()?

```

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

int main(void) {
    char *x = malloc(sizeof(char) * 50);
    printf("Enter your name: ");
    if (x) {
        scanf("%s", x);              // &x returns an EM      
        printf("Name: %s\n", x);
    }
    free(x);
}

```

If I use '&x' I get an EM: format specifies type 'char *' but the argument has type 'char' ** [-Werror,-Wformat]. What does that EM mean?

Googling I have found that char** is a pointer to a pointer. so x is a pointer and '&x' is a pointer to a pointer? Is '&x' the memory address of the pointer and not the address of the value that the pointer is going to point to? In examples I do see & in scanf and well, I am confused.

I feel rather silly but it is bugging me.

2 Answers 2

2

I think you got it. scanf needs a memory address so it knows where to write to.

Whenever you add & you get the memory address of what follows. But in case of strings, what we pass as a string already is a pointer (because the variable is a pointer to the first character of the actual string, with the characters in your example stored in malloced memory on heap).

Note that arrays in most cases behave identical to pointers, even though there usually exists no separate pointer variable like you usually have for strings. The compiler will "fake" one if you use it with & (returning the same memory address as without &). Or maybe it fakes the one without & to make an array more pointer-like. But it does so in a consistent way, so that you can use arrays and pointers interchangeably in most cases.

Your example would have worked the same with this array on stack:

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

int main(void) {
    char x[50];
    printf("Enter your name: ");
    if (x) {
        scanf("%s", x);
        printf("Name: %s\n", x);
    }
}

and this version, oddly enough, would also have worked with &x. But I would still use without.

Stack and heap memory have their own pros and cons, stack variables cease to exist once you leave the block they got declared in (which means you should not return pointers to variables you just declared locally, because they would point to now unused memory). Stack has less overhead, and does not require a free, which is very convenient.

1
  • Thank you for confirming and adding to my reasoning. Logical thinking works but pointers are so intensely weird it's unsettling.
    – Karin
    Commented Jun 1, 2018 at 19:12
1

The reason why you get the error is because the way scanf() works. scanf() takes two inputs, first the format specifier and second a pointer to a variable. Hence, since you declare name as a pointer there is no need to redoit again by adding the & infront of the name. Remember that & is use to get the address - point to - of the variable. Hope this make sense.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .