Iam trying to compile this program but i get warning and when i run vc++ 2010 debugger pops up : (
Here is my code :
#include <iostream>
using namespace std;
int num;
int min(int mas[])
{
int i,minn,index; /* But I have declared them : (((( */
for(i=0;i<num;i++)
{
if(mas[i]!=0)minn=mas[i];
break;
}
if(i==num) return 0;
for(i=0;i<num;i++)
if(mas[i]!=0 && minn>mas[i])
{
minn=mas[i];
index=i;
}
mas[index]=0;
return minn;
}
int main()
{
cin>>num;
int *array=new int[num]; int tmp;
tmp=min(array);
}
and Here is a compiler log :
prog.cpp: In function ‘int min(int*)’:
prog.cpp:6: warning: ‘index’ may be used uninitialized in this function
prog.cpp:6: warning: ‘minn’ may be used uninitialized in this function
What i am doing wrong ? or its is compiler bug ? :)
Thank you :)
You have declared them, but not initialized them. Simply write int minn = 0, index = 0; to avoid the warning. If you don't initialize a variable, its default value is whatever was at that location in memory already; usually garbage.
The thing is, if num is negative, then neither of the for loops in your min() function will execute, and so minn and index will not have been assigned values. The if(i == num) test also won't break out of the function and prevent this from happening. So the last two lines of the function will have completely undefined results.
Sometimes there really isn't a path for the variables to be used uninitialized, though; sometimes the compiler just isn't quite smart enough to figure out all the subtleties. Just give them an initial value to avoid the warning.
Declaration != initialization. When you declare them the variables have random values. Just initialize them to sensible values like -1 for index and minn to a INT_MAX.
But you haven't initialized them : ))))
EX: int i,minn=0,index=0; Imagine that you pass num that equals 0, at the end you would be returning uninitialized value of minn and just before that you would set mas[unknown_number]=0; which will probably cause your app to crash since you will be referencing memory that is most likely beyond your scope. You should do a check in the beggining like if(num<1)return -1;
Suppose the entire array you pass in is 0. Both loops short-circuit and never execute, both minn and index are uninitialized.
Now if this happens, what should be happening? Set the variables to the values that accomplish just that.
As you say in your comment, yes, you have declared your variables, but you haven't initialized them. Initializing a variable means giving it a value. So in this case, you have told the compiler that you want to create three integers, but you haven't told it what values you want to store in those integers. That would be ok if, for every possible path through your function, index and minn were guaranteed to be given a value, but the problem here is that there is a path through your function where minn and index will never be initialized. First of all, here:
for(i=0;i<num;i++)
{
if(mas[i]!=0)minn=mas[i];
break;
}
If you have an array of zeros, then minn is never initialized to a value.
Then further down:
for(i=0;i<num;i++)
if(mas[i]!=0 && minn>mas[i])
{
minn=mas[i];
index=i;
}
first of all, if you had an array of zeros, well what is the value in minn? There is no value. You are asking the compiler to compare mas[i] to a number which doesn't exist. Furthermore, what if mas[i] is always equal to zero? Well now you don't initialize minn or index. Yet at the end of the function, you are attempting to use the value of index to get an integer from the array amd then you return minn (which still equals nothing).
That's the problem you're getting from the compiler. It can see this potential outcome and is warning you that your function can be broken due to these integers never getting a value. To fix it, do what the other lads have suggested and let index and minn equal zero at the start.
Related
For some reason, the value of final_sum is 16 but I didn't initialize a value for that variable, why's that? Isn't supposed to start with 0?
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
int n, sum, final_sum;
cout<<"ff: "<<final_sum<<endl;
cout<<"Input the value for n: ";
cin>>n;
for(int i=1; i<=n; i++){
sum += i;
final_sum += sum;
cout<<"sum: "<<sum<<endl;
cout<<"final sum: "<<final_sum<<endl<<endl;
}
return 0;
}
Isn't supposed to start with 0
No, its initial value is undefined. See https://en.cppreference.com/w/cpp/language/default_initialization
the objects with automatic storage duration (and their subobjects) are initialized to indeterminate values.
If you do
int final_sum{};
Or
int final_sum = 0;
You will have a 0 in your variable.
I suggest you to use -Wuninitialized (or better -Wall). The compiler will raise a warning if you forgot and initialization
If you don't initialize a variable before reading/using it, its undefined behavior. Its value can then be anything, it's unpredictable and always a bad idea. Use
int final_sum = 0;
to initialize it.
From documentation:
The value in an uninitialized variable can be anything – it is
unpredictable, and may be different every time the program is run.
Reading the value of an uninitialized variable is undefined behaviour
– which is always a bad idea. It has to be initialized with a value
before you can use it.
and
The only place where they are useful is when you are about to read the
variable in from some input stream.
Edit : Some may ask "Why my variable still print 0 even though I haven't initialize it?"
From this post :
That is because variables with automatic storage duration are not
automatically initialized to zero in C++. In C++, you don't pay for
what you don't need, and automatically initializing a variable takes
time (setting to zero a memory location ultimately reduces to machine
intruction(s) which are then translated to electrical signals that
control the physical bits).
So when you do :
int final_sum;
The final_sum is just being reserved a memory location, and anything currently inside that location will be printed out by cout. It just happened that there's a big 0 in that spot.
More info : (Why) is using an uninitialized variable undefined behavior?
Declaring the variable globally does the job
int final_sum;
int main() {
your code ...
}
is the same as
int final_sum = 0;
int main() {
your code here ...
}
However, you probably don't want to use global variables and it is always recommended to initialize variables with some value.
So I have been working on a question and this think stumbled upon me. When I declare a variable outside the main function, the program works correctly, that is it reaches the else case of "Friendship is magic" but if the variable is declared inside it returns Chris instead of Friendship statement.
int mis, chr;
int main() {
int a, n, m;
cin >> a;
for (int i = 0; i < a; i++) {
//code here
}
if(mis > chr)
cout << "Mishka";
else if(chr > mis)
cout << "Chris";
else
cout << "Friendship is magic!^^";
}
The input that I am using makes the value of chr and mis equal so it should be evaluating to the else statement but instead it just stops at else if.
"With great power (provided by C++) there must also come great responsibility"
And
"With uninitialized variables comes the undefined behavior"
Variables that are declared at global scope are being initialized by the compiler. However, the variables defined inside any function (i.e, having automatic storage) may contain garbage values (that could be different in each invocation of the program). I recommend always initializing your variables to some value.
int main()
{
int mis = 0, chr = 0;
// ...
return 0;
}
Let's come to your program now:
When I declare a variable outside the main function, the program works correctly, that is it reaches the else case of "Friendship is magic"
It is happening because the variables (on which your if ladder dependent) are being initialized to 0. Since, both variables have same value (0), the else part of the if statement is being executed.
but if the variable is declared inside it returns Chris instead of Friendship statement.
It's a perfect example of undefined behavior. If they are defined inside your function, they will be holding some garbage value and that might not be equal. Hence, what you are observing is an undefined behavior and you might get different results in different machines or even sometimes in a same machine.
I tried your code and it works the same for me in both cases.
So, I would say it changes with editor to editor and always initialize the variable before using it.
Otherwise, we might face the same problem as you face. As it initializes the variables with garbage values.
I'm learning C++.
And I thought that Array[i]=*(Array+i) .
In the code below, if we remove the phrase within the comments(For Loop)
*(x+1) Not equal to When (For-Loop) Existed.
my compiler is mingw.
main()
{
int x[10];
//////////////////////////////////////////////////////////////////
for(int i=0;i<=9;i++)
cout<<"x"<<"["<<i<<"]"<<"--->"<<x[i]<<endl;
//////////////////////////////////////////////////////////////////
cout<<*(x+1);
}
I expected the output of *(x+1) to be the same before and after remove for.
thanks and sorry about my grammar.
The problem is, x in an automatic local variable and never initialized. The contents of the array members are indeterminate.
You cannot have any expected value there. Every time you execute, you'll get indeterminate values.
I am not really sure how or why this works:
#include <stdio.h>
#include<stdlib.h>
#include <limits.h>
#include <iostream>
using namespace std;
int main() {
int min = INT_MAX, min_index;
cout << min <<"\n";
cout << INT_MAX << "\n";
cout << min_index <<"\n";
system("pause");
return 0;
}
There is actual output for min, INT_MAX, and min_index
I know that INT_MAX is part of the limits.h and so min and INT_MAX are the same but min_index isn't given a value why does it display a value.
C++ isn't a memory-safe language. There's no guarantee that a variable has been a assigned a value before it's used.
What you're seeing as the printed value of min_index, is the value in the memory of min_index that just so happened to be left from the last time the memory was set previously.
Reading from such an initialized variable is "undefined behaviour", in that each invocation of this program will likely lead to a different, unexpected result (depending on what was last using the memory that eventually got allocated for min_index).
In a language like C and C++, when you define a variable, like:
int x;
a small block of memory is allocated to the variable. However, we have only declared the variable, and not initialized it, which means that the block of memory that has been allocated to the variable still contains some value that has been left over from previous programs and operations. That value is called a garbage value. This may lead to erroneous results in programs.
To avoid this, declare and initialize variables like this:
int x = 0;
Source: What do you mean by a garbage value in a variable?
See also: How does an uninitiliazed variable get a garbage value?
Because $min_index is not initialized to a specified value but it is assigned to a memory location. If you print min_index without initializing it first, the values on that memory location will be interpreted as data of the type of min_index.
Therefore it is always recommended to initialize a variable, because you will never know, what the value of that memory location is.
you cant initialize min= int_max. the value is showing due to garbage value
Simple code
#include <iostream>
using namespace std;
struct foo {
int bar;
};
struct foo tab[2];
int sum = 0;
int main()
{
tab[2].bar = 3; //this change 'sum' value!
cout << sum << endl;
return 0;
}
result in 3 instead of 0. It is unbelievable, so problably I am missing something. What I have done wrong?
Arrays start at 0, so tab[2] would be the third element, but you only allocated 2 of them.
In this case, sum is in the memory directly after tab, so when you go to where the third tab would be, you're actually in the memory for sum.
Notice that you access tab[2] which is an overflow (its size is 2 so valid indices are 0 and 1).
So tab[2] accesses the memory address of sum.
When you declare your variable
struct foo tab[2];
tab[2] does not exist.
You can only do
tab[0].bar = 3
tab[1].bar = 3
because arrays index starts from 0 and ends at arraySize-1.
If you look closely tab has a length of 2. By accessing the index 2, you are accessing memory out of the tab, which means you are accessing sum.
This is the reason why you are changing sum.
First of all, turn on compiler warnings! If you'd allow the compiler to help you, then it would very likely point out the exact error in this line:
tab[2].bar = 3; //this change 'sum' value!
Depending on which compiler you use, the warning may be as follows:
warning: array subscript is above array bounds
struct foo tab[2]; has two elements with indices 0 and 1, you try access a non-existing 3rd element. This results in undefined behaviour of your program. Whatever results you got, it was just random. Your program could also randomly crash.
Note that your code is also half C and half C++. That's not good. You don't need to write struct foo when you want to refer to the foo type, it's enough to write foo. Instead of a raw array, std::array<Foo, 2> can be used. And using namespace std; should not be used by default.