-2

I was thinking about pointer initialization and tried the following two cases:

#include <stdio.h>

int main(int argc, char **argv)
{
    int *d;
    int f;
    int p;

    *d = 6;

    printf("%d %d %d\n", *d, f, p);

    return 0;
}

This code segfaults at the line (seen in gdb):

*d = 6;

Which makes sense because I am trying store a value at a random address.

I then tried the following:

#include <stdio.h>

int main(int argc, char **argv)
{
    int *d;
    int f = 10;
    int p = 9;

    *d = 6;

    printf("%d %d %d\n", *d, f, p);

    return 0;
}

This runs to completion with the output:

6 10 9

If only f is initialized to 10 (p is not initialized) or vice versa, the program still completes with output

6 10 0

or

6 0 9

(p initialized). I do not understand why this works. My initial guess is that the initialization of either f or p makes space or orients memory to allow for the safe initialization of d. I also thought about stack allocations, but am still unsure.

teirm
  • 11
  • 2
  • 2
    It should be undefined behavior. – MikeCAT Sep 30 '15 at 14:00
  • 2
    It's undefined behavior; anything can happen. "Working" is anything. Though it is not guaranteed that it will work. – Colonel Thirty Two Sep 30 '15 at 14:04
  • 1
    Or rather "it seems to be working for now, even though it has latent bugs" is one of the results of undefined behavior. Go alter some completely unrelated file in the project and then this bug might decide to crash the program. – Lundin Sep 30 '15 at 14:53
  • Prior to this post, I was not familiar with undefined behavior in C. I found the following two links very helpful, and I hope they help those who find this question. [ What Every C Programmer Should Know About Undefined Behavior #1/3](http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html) [A Guide to Undefined Behavior in C and C++, Part 1](http://blog.regehr.org/archives/213) – teirm Oct 05 '15 at 00:26

4 Answers4

2

Your first problem is in *d = 6; as you're trying to to dereference an invalid pointer.

d is not initialized (allocated memory) and it points to an invalid memory location. Any attempt to dereference that will lead to undefined behavior.

FWIW, the second code also produces UB for the same reason.

Additionally, in the first code snippet, by writing

printf("%d %d %d\n", *d, f, p);

where f and p are uninitialized automatic local variable, you're trying to read indeterminate values, which again, produces UB. This is avoided in the second snippet by explicit initialization.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

In your program -

 *d = 6;                          // writing to an invalid memory location

You leave the pointer with uninitialized value. So when you dereference it (*d), you access unauthorized location in memory, resulting in a segmentation fault.

you also try to print uninitialized local variables-

 printf("%d %d %d\n", *d, f, p);   // where f and p are indeterminate 

Therefore , your code invokes undefined behaviour and your program give output which literally can be anything.

ameyCU
  • 16,489
  • 2
  • 26
  • 41
  • I know. However gdb informs me that SIGSEV is received at the line *d = 6. This occurs even if I don't try to print p and f. My question is more about why the second case works. – teirm Sep 30 '15 at 14:05
  • 2
    In both programs, he dereferences an uninitialized pointer (`d` when he does `*d = 6`) which invokes undefined behavior. – Nik Bougalis Sep 30 '15 at 14:05
  • @NikBougalis Yes , that was reason for seg fault . I modified my answer . – ameyCU Sep 30 '15 at 14:14
1

You need to Allocate your memory with malloc()

this work:

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

int main(int argc, char **argv)
{
    int *d;
    int f = 10;
    int p = 9;

    d = /*(int *)*/malloc(sizeof(int) * 1);
    if (!d)
        exit(-1);
    *d = 6;

    printf("%d %d %d\n", *d, f, p);
    free(d);
    return 0;
}
albttx
  • 3,444
  • 4
  • 23
  • 42
1

This code segfaults at the line (seen in gdb):

*d = 6;

Which makes sense because I am trying to give random address to a value.

It does make sense that that segfaults, but your explanation is grossly incorrect. You are not in any way giving / or assigning an address to a value. Rather, you are attempting to store a value at an unspecified address.

It is critically important to understand the difference between d and *d. The former (as you have declared it) is a pointer that is expected to hold the address of an int. The latter is the int that d points to. If d has not, in fact, been initialized to point to an int, then evaluating the expression *d produces undefined behavior.

Undefined behavior is exactly that -- undefined. You cannot expect a similar source of undefined behavior to produce the same actual behavior in other circumstances, and you cannot even rely on the behavior to manifest an obvious indication of brokenness. Anything can happen, including, in principle, what the programmer wanted to happen.

Declaring a pointer variable does not automatically cause any storage to be allocated. There are any number of ways you could initialize d, but one would be

d = &f;
John Bollinger
  • 160,171
  • 8
  • 81
  • 157