garbage values in C/C++ [duplicate] - c++

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How an uninitialised variable gets a garbage value?
How are garbage values generated in C and C++ ? Does the compiler use some random number generation technique for generating garbage values?

If you mean the values of uninitialized variables, those aren't generated. They're just whatever garbage happened to be in that memory location.
int *foo = new int;
std::cout << *foo << std::endl;
New returned a pointer to some address in memory. That bit of RAM has always existed; there is no way to know what was stored there before. If it was just requested from the OS, it'll likely be 0 (the OS will erase memory blocks before giving them out for security reasons). If it was previously used by your program, who knows.
Actually, the results of using an uninitialized variable are undefined. You might get back an unpredictable number, your program may crash, or worse.
Even if you know that its safe to run the above on your platform, you shouldn't rely on that giving a random value. It will appear random, but is probably actually quite a bit more predictable and controllable than you'd like. Plus, the distribution will be nowhere near uniform.

If by "garbage values" you mean the values of uninitialized variables, it doesn't -- the value of an uninitialized variable is undefined by the standard. The garbage value you're thinking of is actually just whatever happened to be stored in that memory right before the storage for the variable was allocated from the stack or heap.
That said, some compilers offer debugging aids that will fill uninitialized variables with some well-known "magic number" to help you catch errors of this sort. For example, Microsoft Visual C++ fills uninitialized stack variables with 0xCCCCCCCC. These are specific to the compiler and usually require that you compile with debugging turned on.

The memory your program happens to use comes up in some state, controlled by how the electrons flowed at power up, funny properties of the silicion, what was in the memory before, and sometimes cosmic rays.
It isn't random, but it is extremely hard to predict.

Related

Can my program use unallocated memory on the free store without my knowledge?

When defining a variable without initialization on either the stack or the free store it usually has a garbage value, as assigning it to some default value e.g. 0 would just be a waste of time.
Examples:
int foo;//uninitialized foo may contain any value
int* fooptr=new int;//uninitialized *fooptr may contain any value
This however doens't answer the question of where the garbage values come from.
The usual explanation to that is that new or malloc or whatever you use to get dynamically allocated memory don't initialize the memory to some value as I've stated above and the garbage values are just leftover from whatever program used the same memory prior.
So I put this explanation to the test:
#include <iostream>
int main()
{
int* ptr= new int[10]{0};//allocate memory and initialize everything to 0
for (int i=0;i<10;++i)
{
std::cout<<*(ptr+i)<<" "<<ptr+i<<std::endl;
}
delete[]ptr;
ptr= new int[10];//allocate memory without initialization
for (int i=0;i<10;++i)
{
std::cout<<*(ptr+i)<<" "<<ptr+i<<std::endl;
}
delete[]ptr;
}
Output:
0 0x1291a60
0 0x1291a64
0 0x1291a68
0 0x1291a6c
0 0x1291a70
0 0x1291a74
0 0x1291a78
0 0x1291a7c
0 0x1291a80
0 0x1291a84
19471096 0x1291a60
19464384 0x1291a64
0 0x1291a68
0 0x1291a6c
0 0x1291a70
0 0x1291a74
0 0x1291a78
0 0x1291a7c
0 0x1291a80
0 0x1291a84
In this code sample I allocated memory for 10 ints twice. The first time I do so I initialize every value to 0. I use delete[] on the pointer and proceed to immediately allocate the memory for 10 ints again but this time without initialization.
Yes I know that the results of using an uninitialized variable are undefined, but I want to focus on the garbage values fro now.
The output shows that the first two ints now contain garbage values in the same memory location.
If we take the explanation for garbage values into consideration this leaves me only one conclusion: Between deleting the pointer and allocating the memory again something must have tampered with the values in those memory locations.
But isn't the free store reserved for new and delete?
What could have tampered those values?
Edit:
I removed the std::cout as a comment pointed it out.
I use the compiler Eclipse 2022-06 comes with (MinGW GCC) using default flags on Windows 10.
One of the things you need to understand about heap allocations is that there is always a small control block also allocated when you do a new. The values in the control block tend to inform the compiler how much space is being freed when delete is called.
When a block is deleted, the first part of the buffer is often overwritten by a control block. If you look at the two values you see from your program as hex values, you will note they appear to be addresses in the same general memory space. The first looks to be a pointer to the next allocated location, while the second appears to be a pointer to the start of the heap block.
Edit: One of the main reasons to add this kind of control block in a recently deallocated buffer is that is supports memory coalescence. That two int signature will effectively show how much memory can be claimed if that space is reused, and it signals that it is empty by pointing to the start of the frame.
When defining a variable without initialization on either the stack or the free store it usually has a garbage value, as assigning it to some default value e.g. 0 would just be a waste of time.
No. The initial value of a variable that is not initialized is always garbage. All garbage. This is inherent in "not initialized". The language semantics do not specify what the value of the variable is, and reading that value produces undefined behavior. If you do read it and it seems to make sense to you -- it is all zeroes, for example, or it looks like the value that some now-dead variable might have held -- that is meaningless.
This however doens't answer the question of where the garbage values come from.
At the level of the language semantics, that question is non-sensical. "Garbage values" aren't a thing of themselves. The term is descriptive of values on which you cannot safely rely, precisely because the language does not describe where they come from or how they are determined.
The usual explanation to that is that new or malloc or whatever you use to get dynamically allocated memory don't initialize the memory [so the] values are just leftover from whatever program used the same memory prior.
That's an explanation derived from typical C and C++ implementation details. Read again: implementation details. These are what you are asking about, and unless your objective is to learn about writing C and / or C++ compilers or implementations of their standard libraries, it is not a particularly useful area to probe. The specifics vary across implementations and sometimes between versions of the same implementation, and if your programs do anything that exposes them to these details then those programs are wrong.
I know that the results of using an uninitialized variable are undefined, but I want to focus on the garbage values fro now.
No, apparently you do not know that the results of using the value of an uninitialized variable are undefined. If you did, you would not present the results of your program as if they were somehow meaningful.
You also seem not understand the term "garbage value", for in addition to thinking that the results of your program are meaningful, you appear to think that some of the values it outputs are not garbage.

C++ Initialize Array Waste Value

I often make mistakes not to initialize the values of the array.
Theoretically, we know that in that case, the arrangement should have a waste value.
In practice, however, many values are initialized to zero.
Therefore, program satisfied with the small examples.
This makes debugging difficult.
Can you tell me why this is happening?
Uninitialized values usually appear to be zero in simple test cases because modern operating systems blank memory before handing it to processes as a security precaution. This won't hold if your program has been running for awhile, so don't depend on it. This applies to both automatic (stack) variables and heap allocations. For stack allocations it's actually worse as the variable can take on a value that the variable can't possibly contain normally, potentially crashing your program outright. When dealing with the Itanium processor, it could crash with a memory fault even when assigning an uninitialized integer variable to another variable.
Or try it in DOS. It will not work because DOS doesn't blank memory.
On the other hand, static and global allocations are guaranteed to be zeroed if not initialized by the standard.
If you want to be warned about uninitialised memory, both g++ and clang++ support the Memory Sanitizer. Just add -fsanitize=memory to your compiler flags and you'll get runtime errors when you read uninitialised memory.

Why are memory locations assigned garbage values?

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
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?
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.
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).
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)
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 ).
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.

Why does my dynamically allocated array get initialized to 0?

I have some code that creates a dynamically allocated array with
int *Array = new int[size];
From what I understand, Array should be a pointer to the first item of Array in memory. When using gdb, I can call x Array to examine the value at the first memory location, x Array+1 to examine the second, etc. I expect to have junk values left over from whatever application was using those spots in memory prior to mine. However, using x Array returns 0x00000000 for all those spots. What am I doing wrong? Is my code initializing all of the values of the Array to zero?
EDIT: For the record, I ask because my program is an attempt to implement this: http://eli.thegreenplace.net/2008/08/23/initializing-an-array-in-constant-time/. I want to make sure that my algorithm isn't incrementing through the array to initialize every element to 0.
In most modern OSes, the OS gives zeroed pages to applications, as opposed to letting information seep between unrelated processes. That's important for security reasons, for example. Back in the old DOS days, things were a bit more casual. Today, with memory protected OSes, the OS generally gives you zeros to start with.
So, if this new happens early in your program, you're likely to get zeros. You'd be crazy to rely on that though; it's undefined behavior if you do.
If you keep allocating, filling, and freeing memory, eventually new will return memory that isn't zeroed. Rather, it'll contain remnants of your process' own earlier scribblings.
And there's no guarantee that any particular call to new, even at the beginning of your program, will return memory filled with zeros. You're just likely to see that for calls to new early in your program. Don't let that mislead you.
I expect to have junk values left over from whatever application was using those spots
It's certainly possible but by no means guaranteed. Particularly in debug builds, you're just as likely to have the runtime zero out that memory (or fill it with some recognisable bit pattern) instead, to help you debug things if you use the memory incorrectly.
And, really, "those spots" is a rather loose term, given virtual addressing.
The important thing is that, no, your code is not setting all those values to zero.

How a garbage value is assigned in c/c++ [duplicate]

This question already has answers here:
How garbage values are assigned to variables in c
(6 answers)
Closed 9 years ago.
In C++/C if we don't initialize a variable, it will have some garbage values right? I would like to know from where these values are coming? Is it assigned by the compiler? Does this value have range? Is it the previous value present in the memory allocated to that variable? If yes can 5 or 500 be a garbage value?
This is not for any coding purpose, I just what to know it for learning.
Any value can be garbage. It's whatever was left over in that spot of memory from the last operation that occurred there. It is unpredictable and never reliable, but it could be 5 or 500.
Assuming the compiler doesn't do anything special (which it might if you're doing a debug build), it'll be whatever happens to be in memory at the time.
It cannot be depended upon.
It could be whatever value was in the memory position previously. It could be a magic value such as 0xCD, placed there by the debugger. It could be set to 0 for you by the compiler. It could be a value which isn't legal for the type (for example, not equal to any enum values).
You get the value that is already there. So yes, this could very well be "5".
Note: if you run in DEBUG mode the environment will usually get zeroed memory, this is one way to get the weird behaviour we call "Heisenbugs" :-)
The garbage value is not assigned, rather the value is already there. When you allocate a variable you are reserving a piece of memory - until you overwrite it that memory will contain whatever "random" information was there before. Check this link which has the answer
Link