-1

in the following example, I want to understand why a value of 4195520 is added to chars[2] (counting spaces).

char input;
int chars[4];  // [0] = newlines; [1] = tabs; [2] = spaces; [3] = all_else 
int i, j;

printf("--\n");
printf("please enter input\n");
printf("~[enter] to end\n\n");
while ((input = getchar()) != EOF) {
    if (input == '\n') {++chars[0];}
    else if (input == '\t') {++chars[1];}
    else if (input == ' ') {++chars[2];}  // 4195520 is added (plus the amount of actual spaces), but only if I add to an array member
                                          // if I increment an integer variable, it counts correctly
    else if (input == '~') {printf("\n"); break;}
    else {++chars[3];}
}

printf("--\n");
printf("the frequency of different characters\n");
printf("each dot represents one occurance\n");
for (i=0; i<=3; ++i) {
    if (i == 0) {printf("newlines:\t");}
    else if (i == 1) {printf("tabs:\t\t");}
    else if (i == 2) {printf("spaces:\t\t");}
    else if (i == 3) {printf("all else:\t");}
    for (j=0; j<chars[i]; ++j) {printf(".");}  // ~4.2 million dots are printed for spaces
    printf("\n");
}

The solution to counting correctly is to initialize the array members to 0, but I want to understand why only whitespace and why only using an array member as a counter, increments to the number 4195520 every time.

verbose
  • 7,827
  • 1
  • 25
  • 40
BlaineM
  • 1
  • 1
  • 3
    There's no sensible explanation. If the array is uninitialized, its members can be anything, including 4195520. –  Aug 26 '13 at 17:46
  • 2
    You're evaluating, incrementing, and assigning data premised on initially-*indeterminate* values, which is **undefined behavior**. – WhozCraig Aug 26 '13 at 17:49
  • @H2CO3 - not true. there IS a sensible explanation, both clearly understandable and explainable. – BlaineM Aug 26 '13 at 17:56
  • @BlaineM So then what is it? –  Aug 26 '13 at 18:00
  • @H2CO3 - why is that specific number given, you mean? We're talking about clearly defined processes, not just something my computer is imagining out of thin air. There's a reason that can be clearly understood, is all I'm saying. I'm wanting to find and understand the logic leading up to a garbage value being added. – BlaineM Aug 26 '13 at 18:09
  • 1
    @BlaineM: "clearly defined" by what? Not by the C standard. The fact that your specific computer might do a specific thing is neither here nor there if you're asking a question about the C programming language. – Crowman Aug 26 '13 at 18:15
  • @BlaineM The reason for a garbage value is the uninitialized value and the undefined behavior. "We're talking about clearly defined processes, not just something my computer is imagining out of thin air." - Well, not quite. This value may be, for example, some garbage that was left there by another process previously occupying your program's physical address space. Guess how the kernel organizes the processes in memory? Basically randomly. It can be the case, for example, that it arranges them according to memory usage. If another process suddenly allocates more memory, your program will be –  Aug 26 '13 at 18:19
  • @BlaineM (cont) stored elsewhere in the RAM upon next run. What if you are playing an online game, and the game server suddenly starts spamming your browser between two program launches, increasing its memory usage? Boom, you have randomized behavior. –  Aug 26 '13 at 18:20
  • If you trace the behavior of your computer, following everything it does up to the execution of your program, you can *in theory* determine what the initial values stored in your `chars` array are going to be. In practice, that determination is going to be extremely sensitive to events beyond your control, and likely beyond your ability to detect. – Keith Thompson Aug 26 '13 at 18:26
  • 1
    In some cases, it may even be sensitive to events that are *in principle* unpredictable, for example if your system's state depends indirectly on the output of some quantum phenomenon. All it takes is receiving *some* data over the Internet from a source that used a [hardware random number generator](http://en.wikipedia.org/wiki/Hardware_random_number_generator#Physical_phenomena_with_quantum-random_properties. 99+% of the time, it's not worth worrying about; just be sure to initialize all your variables before trying to read them. – Keith Thompson Aug 26 '13 at 18:28
  • my usage of "clearly defined" being incorrect and not precise then, but the technical explanations here are what I was going for. thanks all! – BlaineM Aug 26 '13 at 18:52

1 Answers1

3

It's garbage value: some value that just happens to be at the particular memory location because of a previous operation, and has not been cleared. You might be getting 4195520 this time around, but if you run some other program and then re-run your code you'll probably see something different. You'll almost certainly see something different on a different machine.

As you note, the correct way to do the counting is this:

int chars[4] = {0};
verbose
  • 7,827
  • 1
  • 25
  • 40
  • yeah, I found the initializing of the array members solved the issue, but I wasn't aware of garbage value. I kept imagining a process in the compiler going through 4 million additions. I'll read more into garbage values. thanks! – BlaineM Aug 26 '13 at 17:59
  • 1
    @BlaineM Suggest you spend time reading more about *undefined behavior* as well, [such as here](http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior). – WhozCraig Aug 26 '13 at 18:04