I am currently doing a simple problem on codeforce. Basically you are given a string (e.g. "1+3+2") and you have to return it sorted (e.g. "1+2+3"). Only 1,2 and 3 will be used.
I started with:
#include <iostream>
using namespace std;
int main()
{
string str;
int arr[4];
cin >>str;
for(int i = 0; i < str.length();i+=2)
arr[str[i] - '0']++;
}
My idea was to store every occurrence of a number in an array. But I noticed a problem if I would add
cout<< arr[2];
and input "1+2+3", it outputs:
33
However, it should be 1, because 3 only occurred once.
I solved it, by moving "string str;" and "int arr[4]" up, over main:
#include <iostream>
using namespace std;
string str;
int arr[4];
int main()
{
cin >>str;
for(int i = 0; i < str.length();i+=2)
arr[str[i] - '0']++;
cout<< arr[2];
}
Output:
1
Why does it work now?
In your first example, arr
has automatic storage duration and is uninitialized, as a result of default initialization:
int main() {
// default initialization
int arr[4];
// reading from arr at this point (remains
// uninitialized) is undefined behaviour.
}
The effect of default initialization of an array type is that every element of the array is default-initialized. The effect of default initialization on fundamental non-class types is nothing: the elements will remain uninitialized. Reading from such elements (invocation of operator++
upon the elements in your example) is undefined behaviour.
You can e.g. value-initialize arr
using the following syntax:
int main() {
int arr[4]{};
}
with the effect that each element of the array is value-initialized, which in turn has the effect that each element of the array (fundamental non-class type) is zero-initialized.
In the second example, arr
no longer has automatic storage duration but static storage duration, and the rules of static initialization applies, which will lead to arr
being zero-initialized.