Why do I need to initialize an int variable to 0? - c++

I just made this program which asks to enter number between 5 and 10 and then it counts the sum of the numbers which are entered here is the code
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int a,i,c;
cout << "Enter the number between 5 and 10" << endl;
cin >> a;
if (a < 5 || a > 10)
{
cout << "Wrong number" << endl;
system("PAUSE");
return 0;
}
for(i=1; i<=a; i++)
{
c=c+i;
}
cout << "The sum of the first " << a << " numbers are " << c << endl;
system("PAUSE");
return 0;
}
if i enter number 5 it should display
The sum of the first 5 numbers are 15
but it displays
The sum of the first 5 numbers are 2293687
but when i set c to 0
it works corectly
So what is the difference ?

Because C++ doesn't automatically set it zero for you. So, you should initialize it yourself:
int c = 0;
An uninitialized variable has a random number such as 2293687, -21, 99999, ... (If it doesn't invoke undefined behavior when reading it)
Also, static variables will be set to their default value. In this case 0.

If you don't set c to 0, it can take any value (technically, an indeterminate value). If you then do this
c = c + i;
then you are adding the value of i to something that could be anything. Technically, this is undefined behaviour. What happens in practice is that you cannot rely on the result of that calculation.
In C++, non-static or global built-in types have no initialization performed when "default initialized". In order to zero-initialize an int, you need to be explicit:
int i = 0;
or you can use value initialization:
int i{};
int j = int();

Non-static variables are, by definition, uninitialized - their initial values are undefined.
On another compiler, you might get the right answer, another wrong answer, or a different answer each time.
C/C++ don't do extra work (initialization to zero involves at least an instruction or two) that you didn't ask them to do.

The sum of the first 5 numbers are 2293687
This is because without initializing c you are getting value previous stored at that location (garbage value). This will make yor program's behavior undefined. You must have to initialize c before using it in your program.
int c= 0;

Because when you do:
int a,i,c;
thus instantiating and initializing c, you haven't said what you want it initialized to. The rules here are somewhat complex, but what it boils down to is two things:
For integral types, if you don't specify an initializer, the variable's value is indeterminate
When you try to read an uninitialized variable, you evoke Undefined Behavior

Related

Local Variable being changed without manipulation

I'm creating a simple quick sort program that initializes an empty array and asks the users for inputs to determine how many elements are going to be sorted and what elements are going to be sorted.
The problem I am encountering is a local variable is being changed despite being only being referenced to once assigned. Attached below is the code.
int main()
{
int amount;
int numbersarray[] = {};
std::cout << "How many numbers do you want to sort? " << std::endl;
std::cin >> amount;
for(int i = 0; i <= amount; i++){
std::cout << "Enter number to be sorted: " << std::endl;
std::cin >> numbersarray[i];
}
std::cout <<"Amount to be sorted: " << amount << std::endl;
for(int i = 0; i <= amount; i++){
std::cout << numbersarray[i] << std::endl;
}
}
What I expect to be occurring, when I input the amount as 5, I should be able to input 5 elements into the array, instead however the Amount printed is 2 and the maximum elements I can put into the array is 3.
Below is the execution output.
How many numbers do you want to sort?
5
Enter number to be sorted:
5
Enter number to be sorted:
2
Enter number to be sorted:
5
Amount to be sorted: 2
5
2
5
I've tried messing around with the for statement but I don't think I'm doing it right as it hasn't fixed the problem, The manipulation of the for statement I'm doing is changing the condition (i.e !=, <, <=)
You have undefined behavior. Anything can happen. Local variable can change without reason, the program can crash and your computer can format itself with linux 6.9
There are many problem. The first is that your program is invalid according to the standard:
int numbersarray[] = {};
This is not valid. Array need a size:
constexpr int max_amount = 32;
int numbersarray[max_amount] = {};
If you need it to be dynamic, use vector:
std::vector<int> numbersarray;
numbersarray.resize(amount);
Second, you have another source of undefined behavior:
// Iterates too much, numbersarray[amount] is past the end
// ~~~v~~~~~~~
for(int i = 0; i <= amount; i++){
std::cout << "Enter number to be sorted: " << std::endl;
std::cin >> numbersarray[i];
}
It should be:
for(int i = 0; i < amount; i++){
std::cout << "Enter number to be sorted: " << std::endl;
std::cin >> numbersarray[i];
}
To avoid invalid code and undefined behavior, you should enable warnings.
numbersarray is a C-style array with a size of zero and doesn't adjust its size dynamically (most compilers might even fail to compile int numbersarray[] = {}; since an empty initializer isn't allowed for an array with unspecified size).
Writing or reading its elements causes undefined behaviour (which can be access violations, changing unrelated variables, and much more). This is the reason why you might see the values of local variables changing. Someone else that uses the same code could get completely different behaviour, since it is undefined.

Program not running with Array during Initialization

I'm just practicing using arrays. So my program consist of inputting numbers of data type double into the array and have them print out. Simple.
I only limited the numbers down to 4. So the array, num_List[3] is in the code. I've made sure to use the for loops properly for reading and printing out the result.
The first few times I tested the code. I realized that the 4th number in the array was in scientific notation, telling me that I forgot to initialize the array to 0, in this case 0.0, since I'm using double. So I put in this code.
for (index = 0; index <= 3; index++)
num_List[index] = 0.0;
This code should have initialized the arrays of num_List to 0.0. However, when I tested this, nothing came up, after I inputted the 4 numbers. So I made a logical error here or it's something else with the for loop that's causing it to be trapped and not continue the execution.
I've read in the books about this particular way to initialize.
#include <iostream>
using namespace std;
int main() {
double num_List[3]; // These are my variables
int index;
//double num; // Ignore these two for now, for they are to be modified later on.
//double result;
cout << "This program will summarize the numbers you've inputted print out the result. \n";
cout << "And also print out the address of the 1st and 4th address in the array." << endl;
cout << "Please enter the four numbers to be summarized.";
for (index = 0; index <= 3; index++) { // I put this in after I realized my mistake of not initializing my arrays to 0.0.
num_List[index] = 0.0;} // This is where the problem is, I think.
for (index = 0; index <= 3; index++) // This reads in the user the input
cin >> num_List[index];
cout << "The numbers you have inputted is:\n";
for (index = 0; index <= 3; index++) // This prints out the array.
cout << num_List[index] << ", " << endl;
return 0;
}
If you focus on the aforementioned code, and try to compile it, you'll see that my code unfortunately doesn't continue on from there after you input 4 numbers, regardless of whether or type a number and space it up to 4 numbers, or input a number, press the enter key for those numbers. Most likely I've made a obvious mistake, but I'm having some trouble seeing it.
I use Code Blocks, so things are a little different compared to the Bloodshed C++ compiler I used to use to practice codes on.
double num_List[3];
This declares an array with 3 elements, indexed 0 through 2.
for (index = 0; index <= 3; index++)
This loops through 4 indices, 0 through 3. When you do something with num_List[3], you get undefined behavior. In your trial, the undefined behavior fortunately resulted in just some garbage output.

Why my static integer is not showing the changed value in the main function?

Here is my code. Here i is the static integer as global integer. As I know here the value of i should be 8 for n = 4. But it is showing 0. May be there is some lack of knowledge in me. Please let me know what I am missing.
#include<iostream>
using namespace std;
static int i;
int fib(int n){
i++;
if(n==0){
return 0;
}
else if(n==1){
return 1;
}
return fib(n-1)+fib(n-2);
}
int main(){
int n;
cin>>n;
cout<<"fib("<<n<<") = "<<fib(n)<<" calls = "<<i;
}
Here is my output:
fib(4) = 3 calls = 0
Your static integer has nothing to do with it. The problem is due to use of operator<<, order of evaluation and operator precedence / sequence points. The reason is that i gets evaluated first which at this point is equal to 0 and gets sent to output stream. Then the fib(n) function gets evaluated and sent to output stream. Break the expression into two statements instead:
std::cout << "fib(" << n << ") = " << fib(n);
std::cout << " calls = " << i;
This will ensure the the proper order of evaluation where fib(n) gets evaluated first and i gets evaluated second.
The problem here is that in a statement like
cout<<"fib("<<n<<") = "<<fib(n)<<" calls = "<<i;
the output will be in the order you write it, but there is no guarantee for what order the computation of each expression will happen. In your example i is being calculated first, then fib(n).
Try this instead
int main(){
int n;
cin>>n;
int tmp = fib(n);
cout<<"fib("<<n<<") = "<< tmp <<" calls = "<<i;
}
The value i is being read by << before fib(n) is called?
Never "do work" in a diagnostic.
Also you didn't initialise i to 0.
This happens because your compiler is outdated.
As other answers explain, the compiler chooses to read i's value before calling fib(n). However, what they fail to tell is that the current C++ standard requires i's value to be read after calling fib(n). The program is already supposed to do exactly what you expect it to do.
According to C++ compiler support - cppreference, the new evaluation rules have been implemented in GCC 7 and in Clang 4. You may either modify your code to be acceptable to older compilers, or switch to a more up-to-date compiler.
This is a C++17 feature, though, and the default is not to compile in C++17 mode. You might need to add -std=c++17 or similar to your command-line options.

C++11 Why does cout print large integers from a boolean array?

#include <iostream>
using namespace std;
int main() {
bool *a = new bool[10];
cout << sizeof(bool) << endl;
cout << sizeof(a[0]) << endl;
for (int i = 0; i < 10; i++) {
cout << a[i] << " ";
}
delete[] a;
}
The above code outputs:
1
1
112 104 151 0 0 0 0 0 88 1
The last line should contain garbage values, but why are they not all 0 or 1? The same thing happens for a stack-allocated array.
Solved: I forgot that sizeof counts bytes, not bits as I thought.
You have an array of default-initialized bools. Default-initialization for primitive types entail no initialization, thus they all have indeterminate values.
You can zero-initialize them by providing a pair of parentheses:
bool *a = new bool[10]();
Booleans are 1-byte integral types so the reason you're seeing this output is probably because that is the data on the stack at that moment that can be viewed with a single byte. Notice how they are values under 255 (the largest number that can be produced from an unsigned 1-byte integer).
OTOH, printing out an indeterminate value is Undefined Behavior, so there really is no logic to consider in this program.
sizeof(bool) on your machine returns 1.
That's 1 byte, not 1 bit, so the values you show can certainly be present.
What you are seeing is uninitialized values, different compilers generate different code. On GCC I see everything as 0 on windows i see junk values.
generally char is the smallest byte addressable- even though bool has 1/0 value- memory access wise it will be a char. Thus you will never see junk value greater than 255
Following initialization (memset fixes the things for you)
#include <iostream>
using namespace std;
int main() {
bool* a = new bool[10];
memset(a, 0, 10*sizeof(bool));
cout << sizeof(bool) << endl;
cout << sizeof(a[0]) << endl;
for (int i = 0; i < 10; ++i)
{
bool b = a[i];
cout << b << " ";
}
return 0;
}
Formally speaking, as pointed out in this answer, reading any uninitialized variable is undefined behaviour, which basically means everything is possible.
More practically, the memory used by those bools is filled with what you called garbage. ostreams operator<< inserts booleans via std::num_put::put(), which, if boolalpha is not set, converts the value present to an int and outputs the result.
I do not know why you put a * sign before variable a .
Is it a pointer to point a top element address of the array?

Why does a for loop in c++ access a memory location in non-initialized compared to the behavior of a normal cout?

I found this occurrence to be rather interesting, let me explain:
When I initialized a int array, I started to wonder how c++ handles an index with a no initialized value. When directly using cout, c++ directly outputs the values as 0. However, when inserting a for loop right afterwards, with the same purpose it instead points to the values inside the memory location, and pretends they were not initialized.
To regenerate this error, copy & paste the code below onto a compiler. Run it once without the for loop, and once with the for loop.
I am just interested to find out why this occurs.
#include <iostream>
using namespace std;
int main() {
int myArray[4];
myArray[2] = 32;
cout << "\n Val 1: "<< myArray[0] << "\n Val 2: "<< myArray[1]<< "\n Val 3: "<< myArray[2]<< "\n Val 4: "<< myArray[3]<< "\n Val 5: "<< myArray[4];
cout <<"\n ----------------------------";
/*
for(int i = 0; i < 5; i++){
cout << "\n Val " << i << ": " << myArray[i];
}
*/
return 0;
}
You are likely witnessing the work of a (clever) optimizer:
Without the for loop, you access the array elements with a fixed constant, a constant which the optimizer can easily proove will lead to an uninitialized value, which is also never used again. As such, it can optimize away actually reading the element from the uninitialized memory, because it is perfectly entitled to use some constant instead.
With the for loop, you have a second usage of the values (through the use of a dynamic index), and the optimizer has to ensure that the undefined value you read from the array elements in the first cout is the same as the one that is later read within the loop. Obviously, it does not try to unroll the loop - after that it would know how to optimize the reads away.
In any case, whenever you access an uninitialized value, that value is undefined, it can be anything, including zero (even though you are not yet invoking undefined behavior). Whenever you use such a value for memory access (uninitialized pointer etc.), you have undefined behavior at its worst.