0

I try this program in CS50 Week 4 memory. I noticed there is a pattern on the garbage values. Initially, I thought garbage values should be randomize. But, it looks like there is different pattern depended on the number of garbage value requested.

Code:

#include <stdio.h>
#include <stdlib.h>
int main (void)
{
    //Create an array of 3
    int scores[3];

    //Print 3 random garbage values
    //scores[0] have big random values
    //scores[1] have 3276X
    //scores[2] have 0
    for (int i = 0; i < 3; i++)
    {
        printf("%i\n", scores[i]);
    }
}

Result:

pset4/W4.1/ $ ./garbage
-1498813296
32767
0
pset4/W4.1/ $ ./garbage
-1011161520
32764
0
pset4/W4.1/ $ ./garbage
1340521040
32765
0
pset4/W4.1/ $ ./garbage
1244491248
32765
0
pset4/W4.1/ $ ./garbage
-1200874656
32764
0

Can anyone help to explain what is happening here? Thanks!

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Consxious
  • 53
  • 6
  • The array scores is uninitialized and has indeterminate values. – Vlad from Moscow Mar 09 '22 at 16:23
  • 1
    Accessing uninitialized memory is undefined behavior. Memory is allocated by the operating system. Which operating system are you using? You could dig into the OS's guts to find out why you're seeing these values exactly, but there's not much reason to do such digging unless you're a security researcher or something similar. – JohnFilleau Mar 09 '22 at 16:23
  • 1
    You could inspect the machine code to see specifically what has been stored in those memory addresses, if anything, before you accessed them. – JohnFilleau Mar 09 '22 at 16:25
  • 4
    "randomized" implies that there is some random number generator which is intentionally being executed in order to produce the "garbage values". Obviously, there isn't one. – Eugene Sh. Mar 09 '22 at 16:25
  • 1
    I’m voting to close this question because it is asking about platform-specific undefined behavior. – Random Davis Mar 09 '22 at 16:26
  • 1
    @EugeneSh. I don't think that's as "obvious" as you claim, especially to a beginner. – JohnFilleau Mar 09 '22 at 16:26
  • 1
    Thinking of uninitialized values as "random" is an error. See for instance https://stackoverflow.com/questions/31739792/is-uninitialized-local-variable-the-fastest-random-number-generator. – Nate Eldredge Mar 09 '22 at 16:26
  • 1
    "_I thought garbage values should be randomize._": For some reason that seems to be taught often, but it is completely incorrect. – user17732522 Mar 09 '22 at 16:33
  • 1
    @user17732522 I think that phenomenon if true could be caused by teachers or students conflating "unknown" with "random". In the vernacular, "random" is often used as a synonym for "unknown". – JohnFilleau Mar 09 '22 at 16:45
  • 1
    In general, you're accessing stack locations that were previously used by other functions. In the case of main(), that will typically be the initialization code for the C runtime library. No guarantees on how that code behaves, but it tends to be predictable and not usable as a seed for rand(). – Hans Passant Mar 09 '22 at 17:08
  • I’m voting to close this question because an answer would require knowledge of the exact assembly instructions emitted by the compiler, which OP has not provided. – Andreas Wenzel Mar 09 '22 at 17:52
  • If you want an answer to your question, then you will probably have to inspect the program in a debugger, by running one assembly instruction at a time. This would require knowledge of assembly language. – Andreas Wenzel Mar 09 '22 at 18:00

1 Answers1

0

Assuming x86_64, when you declare an array like that, the compiler simply makes room on the stack, something like:

sub $12, %rsp (12 bytes for 3 integers)

Then when you access the array you're actually looking at the stack. I know you have a 64 bit OS because if you take scores[0] + scores[1] << 32 you get something similar to 0x0000 7FFC 4A2D 6DF0 and it just so happens that the stack starts around 0x0000 7FFF FFFF FFFF and growing down. So what your looking at is a pointer on the stack (probably a return address from a previous call) and you know that the bottom 32 bits of the next values on the stack is 0, maybe a local variable of the function, who knows.

The important part is that the stack won't change that much (especially in the 32 upper bits) and this is why you're noticing this pattern of 32 764 (0x7FFC).

Read more: https://en.wikipedia.org/wiki/X86_calling_conventions

Hadron
  • 441
  • 3
  • 13
  • Thanks for the answer! It pretty good in explaining the 0 and 32764. It is not completely random. This link added some sense into the answer too. https://stackoverflow.com/questions/31739792/is-uninitialized-local-variable-the-fastest-random-number-generator – Consxious Mar 10 '22 at 15:17