1

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.

1

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
    Jun 1 '18 at 19:12

You must log in to answer this question.

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