0

I'm writing a program in which I fscanf a file and write to the same memory address repeatedly. I tried the following:

FILE *f = fopen(fname, "r");
int* num;
while(fscanf(f, "%d,", num) != EOF)
 {
    printf("%d\n", *num);
} 

which, when I run it, produces Bus Error 10, which means to the best of my understanding that I'm trying to write to an unauthorized address. The following works, however:

FILE *f = fopen(fname, "r");
int num;
while(fscanf(f, "%d,", &num) != EOF)
{
    printf("%d\n", num);
}  

Both compile fine, as I'd expect. What I don't understand is why I can write directly to a memory address but not a pointer to that address. And if they're not the same, why does it compile?

  • In the first example, you're telling fscanf to write to the address contained in num - tell me, what address does num contain? In the second example, you're tellling it to write to the address of num. – user253751 Jul 25 '16 at 2:00
  • Code has 2nd problem while(fscanf(f, "%d,", num) != EOF) should be while(fscanf(f, "%d,", num) == 1). Otherwise entering "x" may start an infinite loop. Compare to what you want, not compare against one of the return values that you do not want. – chux - Reinstate Monica Jul 25 '16 at 19:17
3

In your first attempt, "num" is an uninitialized pointer, and fscanf (which is expecting a pointer) is attempting to store an int through that pointer. But "num" is probably pointing into protected memory (probably location 0), since it has not been initialized to point anywhere.

In your second attempt, "num" is an int, and memory has been allocated for it by its definition "int num;". Then, fscanf is given a pointer to that memory location, and successfully stores the int, because the memory location is valid (which it was not in your first attempt).

| improve this answer | |
3

Both compile fine, as I'd expect.

Both do not compile fine. I get compiler warnings on the first (the one that is wrong) from multiple compilers if I set the compiler warning level to a reasonable value such as -Wall with gcc and clang. As a general rule, it's best to always enable a high level of compiler warnings, and only disable them when you're using a needed third party library that does not compile clean to your standards generates lots of warnings. (Grr. Hate when that happens.)

A halfway decent compiler will detect that the pointer has not been initialized in this case. The general problem of determining whether a variable has been assigned a value prior to being accessed is equivalent to solving the halting problem. Accessing an unassigned variable is deemed to be undefined behavior rather than an error because of this.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.