What determines the "random" location pointed to by uninitialized pointers? [duplicate] - c++

This question already has answers here:
Why is the phrase: "undefined behavior means the compiler can do anything it wants" true?
(2 answers)
Uninitialized variable behaviour in C++
(4 answers)
What happens to uninitialized variables? C++ [duplicate]
(3 answers)
Where exactly does C++ standard say dereferencing an uninitialized pointer is undefined behavior?
(7 answers)
What are the debug memory fill patterns in Visual Studio C++ and Windows?
(3 answers)
Closed 5 months ago.
For uninitialized pointers, such as
int * temp;
what determines the random location in memory that they end up pointing to? Does c++ use a random number generator to fill a memory address for my uninitialized pointer?

An uninitialized variable usually contains whatever pre-existing data was already present in the memory that the variable occupies.
Although, some compilers do fill in uninitialized memory with preset byte patterns in debug builds to aid in debugging. See Debug values for some examples, and also see What are the debug memory fill patterns in Visual Studio C++ and Windows?

Nothing, it's undefined. It is not "random", it is simply non-deterministic. in practice, the value of any initialised variable is determined by whatever happens to be in the memory that the variable occupies. That may for example be leftover from previous operations, as initialised by the system on start-up, or just however the physical hardware behaves. None of that is deterministic but unlikely to be in any sense random.
The point is that undefined behaviour is usually the result of the compiler doing exactly nothing and accepting the result will be undefined. So no, the compiler does not generate a random number - that would be initialisation. Pointless initialisation, but initialisation nontheless.

Related

vector::reserve and built-in types [duplicate]

This question already has answers here:
What does vector::reserve do? [duplicate]
(2 answers)
Closed 7 years ago.
Please don't mark this as duplicate without having read it as a whole. This is not a "what does std::reserve do" question.
Is it an error to write to a vector::reserve'd address with built-in types?
vector<int> vec;
vec.reserve(10);
vec[5] = 24; // Is this an error?
I understand that objects aren't initialized but since those are just integers and space is allocated by reserve and this is done in contiguous storage, is this an error at all?
It is an error because it is undefined behavior, according to the standard. This may not result in any observable problems, but it is still an error. Some implementations will do bounds checking and throw an exception in debug mode. They can do that, and it is perfectly standard compliant to do so, because you invoked undefined behavior.
Yes, this is an error.
And this is also the difference between vector::reserve and vector::resize. As you have said, it has to with the the vector element being unitialised.
Refer to this excellent thread on SO for a difference between the two.

Where do values from unintialized variables come from? [duplicate]

This question already has answers here:
How does an uninitiliazed variable get a garbage value?
(5 answers)
Closed 8 years ago.
When you declare a local variable i like so :
int i;
And you use this variable, you will get undefined behaviour because i isn't initialized yet. But i holds a value, a "garbage" value, where does this value come from? is it from a random place in memory?
You don't know, you can't tell. Undefined behavior means that anything can happen.
That said, in practice on most implementations and most of the time int i; will reserve sizeof(int) bytes on the stack (which is usually somewhere in main memory), so the value of i will be whatever happens to be on the stack at this moment.
But don't rely on it, and remember that this isn't always true.
Its whatever was in memory at &i before.

pointing to a memory address outside an array boundary [duplicate]

This question already has answers here:
Take the address of a one-past-the-end array element via subscript: legal by the C++ Standard or not?
(13 answers)
Access element beyond the end of an array in C
(4 answers)
Closed 8 years ago.
I was wondering if accessing an array outside its boundary(line 2 in the following code sample) would ever produce an error?
int a[20];
int* ptr = &a[20]; // line 2
int count=20;
do
{
ptr--;
printf("%d",*ptr);
}while(--count!=0);
According to C Traps and Pitfalls:
But how can it make sense to refer to an element that doesn't exist?
Fortunately we do not have to refer to this element, merely to its
address, and that address does exist in every C implementation we have
encountered. Moreover, ANSI C explicitly permits this usage: the address
of the nonexistent element just past the end of an array may be taken and
used for assignment and comparison purposes. Of course it is illegal
actually to refer to that element!
Trying to access memory beyond the end of the array is undefined behavior. However, It is perfectly legal to have a pointer to point at one element beyond the end of the array.
The distinction between pointing to a certain address and accessing it is important.
For example, you can use the following to find the size of an array arr
int size = (&arr)[1] - arr;
Accessing memory address outside an array boundary may not crash the the process always. But certainly it will corrupt the address space if you modify the data. Also, sometime memory address outside an array boundary will really lie outside the process address space, that will result in seg-fault.
Anyway, this is a dangerous. It will introduce hard to narrow-down error. The memory corruption, or weird behavior of the program will manifest at some other place, and we will spend hours and hours finding the needle in the haystack.
Modifying the address past array boundary will never produce a compiler error, since C compiler doesn't treat it as error.
However on some machines if this address is not allowed to be accessed, you may get a Runtime Error (Seg Fault).
This is similar to writing to address 0 (NULL).
On a microprocessor/microcntroller/embedded devices on some architectures, you may be allowed to write at address 0, it is perfectly valid but on some other machines you may get SEGFAULT.
That is why this is also termed as undefined behavior.
Your code does not access memory beyond the end of the array.
so changes your code little. Count changed to 100 from 20
#include<stdio.h>
int main() {
int a[20];
int* ptr = &a[20]; // line 2
int count=100;
do
{
ptr--;
printf("%d",*ptr);
}while(--count!=0);
return 0;
}
see http://codepad.org/X8yqrnDC
NO at compilation it will not give any error.
But at run time it might get segmentation fault.
as per standard its undefined behavior

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

garbage values in C/C++ [duplicate]

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.