this might be a noob question, but still i am so confused why this happens.
So this code works just fine:
int *m,g;
g=1;
m[0]=1;
cout<<m[0];
and this one reports error:
int *m;
m[0]=1;
cout<<m[0];
Could this be a bug?
You are using an uninitialized array and you try to access it causing you an undefined behaviour
according to the standard
If no initializer is specified for an object, the object is
default-initialized. When storage for an object with automatic or
dynamic storage duration is obtained, the object has an indeterminate
value, and if no initialization is performed for the object, that
object retains an indeterminate value until that value is replaced ...
If an indeterminate value is produced by an evaluation, the behavior
is undefined
you should initialized like this before
int *m=new int[size_you_want_give_to]
eg
int *m=new int[5]; // array of 5 elements
Related
How do we know pointers are not initialized to NULL by default?
There is a similar questions directed at Why aren't pointers initialized with NULL by default?
Just for checking, here is a very simple code just to see if a pointer is set to NULL by default.
#include <iostream>
using namespace std;
int main()
{
int* x;
if(!x)
cout << "nullptr" << endl;
return 0;
}
and at the output, I received nullptr message. I appreciate if someone can clarify this.
How do we know pointers are not initialized to NULL by default?
Because we know that the standard says that default initialised pointer has an indeterminate value if it has automatic or dynamic storage. Quote from the standard (draft):
[dcl.init] If no initializer is specified for an object, the object is default-initialized. When storage for an object
with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if
no initialization is performed for the object, that object retains an indeterminate value until that value
is replaced. ...
And further:
[dcl.init] To default-initialize an object of type T means:
— If T is a (possibly cv-qualified) class type [pointer isn't a class, so we don't care]
— If T is an array type [pointer isn't an array, so we don't care]
— Otherwise, no initialization is performed.
I have declared a char (and also int) pointer without initializing it , and I got null pointers.
Reading an indeterminate value has undefined behaviour. Quote from the standard (draft):
[dcl.init] ... If an indeterminate value is produced by an evaluation, the behavior is undefined except in the
following cases: [cases which don't apply here]
The question you linked to handles variables with local storage duration exclusively, so I assume you refer to these as well.
Such variables are not initialised if you don't do so yourself, so they get the value of whatever was written in their memory location before (standard wording: their value is 'indeterminate') – nothing speaks against, though, that this memory already is zero – by pure accident!
You can try the following:
void test()
{
int* p; // uninitialized
std::cout << p << std::endl; // undefined behaviour!!!
// (that's what you most likely did already...)
// now something new: change the memory...
p = reinterpret_cast<int*>(static_cast<uintptr_t(0xaddadaad));
}
int main()
{
test();
// again something new: call it a SECOND time:
test();
}
As this is undefined behaviour there are no guarantees at all that you will get any meaningful output – chances are, though that the memory of first function call is reused in second one and you might get output ressembling to the following:
00000000
addadaad
So even if there just happened to be all zero memory at programme start, it might differ from that at some later point while your programme is running...
The following is the code I am trying to run
#include<bits/stdc++.h>
using namespace std;
int main()
{
bool x[101010];
for(int i=0;i<101010;i++)
{
if(x[i])
cout<<i<<" ";
}
return 0;
}
As far as I know, the default value of boolean type variables is false. However, for the above code from index 94758-101008 value of i is being printed which means they are default initialized as true.
Can anyone please help me in figuring out where am I going wrong?
Your problem can be reduced to this:
bool x;
std::cout << x;
A boolean is a fundamental type. Default initializing automatic variables of a fundamental type leaves them with indeterminate values. Not false, but indeterminate. Using those values leads to undefined behavior. This is what you are seeing.
The reason you see random values is that "behind the curtain" a boolean is an integer type that the compiler enforces only two values on. But if you don't initialize it explicity, you'll get whatever random junk is that memory.
The solution is to explicitly value-initialize your variables. For an array, it would look like this:
bool x[101010]{};
That will recursively value initialize each element of the array, and to value initialize a bool is indeed to set it to false.
the default value of boolean type variables is false.
It's not true here. For default initialization,
if T is a non-POD (until C++11) class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object;
if T is an array type, every element of the array is default-initialized;
otherwise, nothing is done: the objects with automatic storage duration (and their subobjects) are initialized to indeterminate values.
x is declared as local object with automatic storage duration, and it's an array with non-class type; then the value of all the elements of x will be indeterminate values.
I am getting different values for the a variable which is an int.
Although I know I am not initializing it, the value changes from 32767 32766 32765 and 32764 for variable a (with code version 1) and its always 0 with code version 2.
I know I don't have to leave variables uninitialized, just asked this question to see if anybody knew what is happening behind the scenes at runtime, I am using gcc .
whith code version 1
#include <iostream>
int main()
{
int a;
int *b = new int; // <----- this line
std::cout<<a<<std::endl;
std::cout<<*b<<std::endl;
return 0;
}
whith code version 2
#include <iostream>
int main()
{
int a;
std::cout<<a<<std::endl;
int *b = new int; // <----- same line moved here
std::cout<<*b<<std::endl;
return 0;
}
You read uninitialized memory. This is undefined behavior. That means the C++ language rules give literally no guarantee what happens when you run this code, at all. You may see the values you observed, nothing at all, crash your PC or set your house on fire. All equally legal outcomes of running this code.
In practice this will only print unpredictable garbage values in the range of int of course, dependent on what just happens to be left over in your memory and do nothing interesting.
Proof from the standard (N4140) for the non-believers:
When storage for an object
with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if
no initialization is performed for the object, that object retains an indeterminate value until that value is
replaced (5.17). [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. —
end note ] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the
following cases:
[8.5 (12)], emphasize mine, the exceptions following this don't apply.
It's an unchecked coincidence in a highly complex system.
That may be the best answer you'll get regarding why uninitialized memory in your computer is showing you the pattern you see.
See also...
The c++ statement new int allocates memory from the heap but it doesn't initialize it. So whatever was on the heap or memory from before is being read. You have to do int *b = new int(0) to initialize what b is pointing to with 0.
(Assuming includes/namespace std/prototypes in the lines above code)
1) Is it safe to create a reference to a declared variable that isn't initialized?
myVariable is declared in line 2 and then myRef is set to reference the uninitialized myVariable in line 3.
Is this something that shouldn't be done?
1- int main(){
2- string myVariable;
3- string& myRef = myVariable;
4- {
2) Is it safe to initialize an uninitialized variable by passing itself through as a reference to a function?
myVar is declared on line 2 and then initialized on line 3 but it uses its uninitialized self as an arguement in the function askText. Inside the function on line 3('7'), the reference text_to_initialize gives myVar a value finally.
Is it safe to intialize with yourself as an arguement in line 3?
1- int main(){
2- string myVar;
3- myVar = inputText(myVar);
4- }
5-
6- string inputText(string& text_to_initialize){
7- cin >> text_to_initialize;
8- return (text_to_initialize + "!");
8- }
All of the above are ok, since none of them perform lvalue-to-rvalue conversion on the indeterminate value. It's even permitted to bind a reference to a variable with non-trivial initialization before that initialization has completed.
The rule is found in section 8.5:
If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced (5.17). [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. —end note ] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:
and the cases involve narrow character types, so not applicable here. What is important is that no evaluation produces an indeterminate value (which would happen as a result of lvalue-to-rvalue conversion).
As John points out, in your particular case, the default initialization of a std::string is not "no initialization", so you don't even have an indeterminate value to begin with. But you'd be ok even for primitive types with no default initialization.
I have been mucking around with C++ once again and noticed a strange behavior regarding the initialization of an array when declared as a pointer inside a class member method or inside the main() function.
int * p = new int[20];
What I would expect to happen is that the pointers will remain uninitialized with random values as they do with
int arr[20];
But instead they are all zeroed. What is going on?
Even though they're zero (this is loosely put, see below), they're not initialized.
Actually, you can't tell they're zero, because if you read the values, you run into undefined behavior. You can't read an un-initialized variable.
To have the array value-initialized, you can do:
int * p = new int[20]();
// ^^
// note parenthesis
but otherwise no, it's not initialized.
p is a pointer to an integer, and it is initialized with the result of a new[] expression. That expression returns the address of the first element of a dynamically allocated array of integers. The array itself is not initialized and contains indeterminate values. If you had said new int[100](), the array would have been zero-initialized instead.