1

I always wondered why there are garbage values stored in a memory space. Why cant the memory be filled with zeros. Is there a particular reason?

For example:

int a ;
cout<<a //garbage value displayed
luk2302
  • 55,258
  • 23
  • 97
  • 137
m0bi5
  • 8,900
  • 7
  • 33
  • 44
  • @MarcGlisse enlighten me – m0bi5 Apr 17 '15 at 16:35
  • You should read [this answer](http://stackoverflow.com/a/1422774/4516316) on [How an uninitialised variable gets a garbage value?](http://stackoverflow.com/questions/1422729/how-an-uninitialised-variable-gets-a-garbage-value) – Arun A S Apr 17 '15 at 16:39

6 Answers6

8

Assigning zeros takes time and is not always what the programmer wants to do. Consider this:

int a;
std::cin >> a;

Why waste time loading a zero into the memory when the first thing you are going to do is store a different value there?

Galik
  • 47,303
  • 4
  • 80
  • 117
  • 2
    @MohitBhasi No. The garbage is there because *nothing* was done so the memory contains whatever random value happened to be there already. – Galik Apr 17 '15 at 17:56
1

Modern OSs do initialise memory to 0 before your process first gets access to it. But once it's been used once there's generally no point zeroing it out again unless there's a specific need. The "garbage values" are just whatever was last written to that memory.

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
  • To illustrate, try "static int a ; cout << a ;". – user3344003 Apr 17 '15 at 18:03
  • That has completely well-defined behaviour in C++ (as I suspect you know) - but there the variable is required to be initialised. It becomes more interesting without the `static`. – Alan Stokes Apr 17 '15 at 18:49
1

Because it's expensive to clear memory (or certainly was), and in the vast number of common cases it wasn't needed.

In the example you show it's stack memory. It would be prohibitively expensive to zero this out each time (basically every function call would have to clear a lump of memory).

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
pm100
  • 48,078
  • 23
  • 82
  • 145
1

For (mostly historical) performance reasons. Zeroing out memory locations that get assigned a proper value later is unnecessary work and one of c/c++ slogans is "You don't pay for what you don't need".

Usually you should always properly initialize a variable right when it is declared anyway, but especially in c, you sometimes just don't know yet, what the initial value of a variable should be.

EDIT: If your question is about where that garbage data comes from: It is just the data that has previously been stored at the same physical address. Lets say, you are calling the following two functions directly after another:

void foo(){
    int a=5;
}
void foo2() {
    int b;
    std::cout << b << std::endl;
}

int main() {
    foo1();
    foo2();
}

it is quite likely,that (in debug mode) the output of your program will be 5 (I believe, this is actually UB, so - taking into account compiler optimizations - anything can happen, of course)

MikeMB
  • 20,029
  • 9
  • 57
  • 102
  • @KarolyHorvath: It still has its benefits of course, but there are far less instances now (compared to c) where you can't properly initialize a variable at the point of declaration and in the cases, where this is still true (like the authors example), the cost of initializing a local variable is really not that big on most systems. If c++ was designed today and without the need to be backwards compatible, I guess they would have decided differently on many things. – MikeMB Apr 17 '15 at 16:45
  • Also in some cases (even in c), where a needless zero-initialization would occur, the compiler can probably prove, that the location is only read from after it has been written to, so the initialization could silently be discarded for those cases. – MikeMB Apr 17 '15 at 16:53
  • "the cost of .. is really not that big" - the same argument could be demonstrated for nearly all the other features for which you don't pay for because you don't use. these small things matter - for example when you are in a tight loop: an extra instruction or a procedure call can make a big difference. also, these small things can add up to a lot... as for what the language would be.. I don't want to comment - it's pure speculation. – Karoly Horvath Apr 17 '15 at 17:03
  • 1
    Please show me a tight loop, where a) you can't initialize the variable right away b) the compiler can't optimize the initialization away c) you cannot afford the initialization cost. Again, I don't say, that it doesn't have its benefits, I just believe that - mostly thanks to better compilers - it would be far less of a problem than most people think. – MikeMB Apr 17 '15 at 17:18
  • @KarolyHorvath: On the other hand, you can of course ask what a zero-by-default policy would actually buy you. Code that reads from an uninitialized memory location today would most probably still be buggy, even if that read would always return zero. It would only make a difference for people that come e.g. from Java who do expect it to be zero. – MikeMB Apr 17 '15 at 17:23
  • The problematic cases of zero initialisation these days are more often really big arrays - the cost of uselessly initialising a million `float`s is significant. – Alan Stokes Apr 17 '15 at 19:29
  • @Alan Stokes: I guess that depends on the definition of "significant". On my desktop PC this takes roughly 1ms, which would be a problem in a loop, but are there really instances, where you allocate a buffer of that size more than once in performance critical code? – MikeMB Apr 19 '15 at 21:33
  • What about a billion? – Alan Stokes Apr 20 '15 at 20:36
  • @Alan: Well, if you are in the habit of dynamically allocating and freeing your whole system memory in a tight loop, then a) you found a situation where not zero-initializing arrays is still beneficial and b) you should seriously reconsider your coding practices ;). No, seriously, I'm sure there are still many applications, where this behaviour has a noticable impact. But I personally would have no problem with a default zero-initialization policy accompanied by special primitives for raw memory allocation. – MikeMB Apr 20 '15 at 21:26
  • @MikeMB: Calling an external method which will sometimes use and sometimes not use various arguments, based upon information known to the programmer but not the compiler, with arguments which may or may not need to be computed. On systems that would allow it, optimal code would be to pass unitialized values to the routine in cases where it was going to ignore the passed-in values; the programmer might recognize the cases where initialization should be skipped, but the compiler might not. – supercat Apr 21 '15 at 20:54
  • @supercat: I think, I don't understand what you mean. Are you talking about something like optional function parameters? – MikeMB Apr 22 '15 at 22:55
  • @MikeMB: `int f(int mode) { int p1,p2; if (mode & 1) p1=g1(); if (mode & 2) p2=g2(); h(mode, p1, p2); }`. On many systems, letting `h` pass arbitrary values to the second and/or third parameter slots when the bottom bits of `mode` aren't set could, if allowed, be cheaper than ensuring that it always passes some known value, if one could ensure that passing the indeterminate value to something that never uses it would have no effect. – supercat Apr 22 '15 at 23:07
  • @supercat: Actually, if you pass p1 and p2 by value, this would be undefined behavior and passing them by reference would be more expensive than zero initializing them. Also such code would not be robust against implementation changes in of `h`. This shows exactly my point: The performance impact of zero initializing would (in most cases, not all) be negligible, but would sometimes prevent hard to identify Bugs. Now my *personal* opinion is, that it would be better to just always zero initialize values and have some special (ugly) syntax for when you e.g. don't want to initialize a big buffer. – MikeMB Apr 23 '15 at 07:41
  • @MikeMB: The right approach, which is supported by some compilers but is unfortunately missing from the standard, would be to have a pseudo-identifier like __INDETERMINATE which is allowed to appear as any value that isn't a trap representation, and initialize variables to that. That would allow a compiler to generate optimal code in situations like the above. Otherwise, if the programmer knows that `h` will never use the passed-in values when certain `mode` bits are clear, but the compiler doesn't, there's no way to avoid wasting instructions writing values that are never read. – supercat Apr 23 '15 at 13:45
  • @MikeMB: I would expect that in the majority of cases where programs use Undefined Behavior, the standard fails to define a reasonable way of achieving the behavior that the program's intended platform would yield; the proper remedy for that situation should be to define convenient standardized ways of requesting such behaviors, but unfortunately standards-writers haven't seen fit to do that. If I have an `int x` and I want to scale it by 2^p, I'd consider `x<<=p` to be clearer than `x=(unsigned)x << p`, and it worked just fine on 99% non-oddball compilers for non-oddball systems. – supercat Apr 23 '15 at 13:55
0

The garbage values you are getting are the values that were previously stored in that address. But in C++ ( and many other languages ) , initializing them all to zero is quite an expensive task which the compiler does not do. That would waste a lot of time which the compiler could have used for some other purpose. So, assigning new values is not done by the compiler.

But there are other compilers that initialize them to 0, but C++ is not one of them.

Normally, the compiler will expect you to give the new variables a new value. Like

int a = 0;  // this is not so hard to do

or

int a;
std::cin >> a ;

So, us assigning a value is much more efficient than the compiler initializing it and then overwriting it.

if you don't assign them values before accessing them, the compiler will give you a warning about uninitialized variable. ( if you have compiler warnings turned on ).

Arun A S
  • 6,421
  • 4
  • 29
  • 43
0

The garbage values come from what is present in the memory space. In your case you have only declared the variable and not initialised it. When a variable is declared, and not initialised, memory is allocated for that variable but not cleared, mostly for performance reasons. Therefore, it may contain an initial value that you do not expect it to contain, which can happen for several reasons. According to Code Complete Chapter 10, a few reasons include:

  • The variable has never been assigned a value. It's value is whatever bits happened to be in its area of memory when the program started.
  • The value in the variable is outdated. The variable was assigned a value at some point, but the value is no longer valid.
  • Part of the variable has been assigned a value and part has not (specifically relates to an object that may have several data members).

A good practice is to declare and initialise a variable as close as possible to where they're first used i.e. follow the Principle of Proximity by keeping related actions together.

ccoder83
  • 504
  • 6
  • 15