I was solving a problem on codechef in the DECEMBER contest - https://www.codechef.com/DEC19B/problems/BINADD . Somewhere in the code I put this loop:
for(i=0;i<=(pos.size()-2);i++)
{
if(pos[i]<0)
continue;
else if(len<(pos[i]-pos[i+1]))
len=pos[i]-abs(pos[i+1]);
}
Here pos is a vector declared as: vector<int> pos;
For these values the code shows a SIGSEGV:
size of pos = 1, pos[0]=0, len=0
But if I replace i<=(pos.size()-2)
with i<(pos.size()-1)
in the loop there occurs NO SIGSEGV. Does anyone have an explanation
NOTE: 1) Full code:
#include <bits/stdc++.h>
using namespace std;
void func()
{
int i=0,len=0,index=0;
string a,b;
cin>>a>>b;
if(b=="0") {std::cout << 0 << std::endl;return;}
else if(a=="0") {std::cout << 1 << std::endl;return;}
int n1,n2;
n1=a.length();
n2=b.length();
if(n1<n2)
{
i=n2-n1;
while(i--)
a="0"+a;
}
else
{
i=n1-n2;
while(i--)
b="0"+b;
}
std::vector<int> pos;
i=a.length();
while(i--)
{
if(a[i]=='0'&&b[i]=='0')
pos.push_back(-i);
if(a[i]=='1'&&b[i]=='1')
pos.push_back(i);
}
for(i=0;i<=(pos.size()-2);i++)
{
if(pos[i]<0)
continue;
else if(len<(pos[i]-pos[i+1]))
len=pos[i]-abs(pos[i+1]);
}
if(pos[i]>=0)
if(len<(pos[i]+1))
len=pos[i]+1;
std::cout << (len+1) << std::endl;
}
int main() {
int t,n;
std::cin >> t;
while(t--)
func();
return 0;
}
2) For the test case:
1 1 1
The above code shows SIGSEGV .
If the size of pos
is 1
, pos.size()-2
is not equal to -1
, it is the maximum value which a size_t
(which is an unsigned type) can hold on your system. So the loop runs till i
is a very very large number.
There is a define for the maximum number: SIZE_MAX
. It is usually on modern 64bit systems 18446744073709551615
.
for(i=0;i<=(pos.size()-2);i++)
is for pos.size()==1
an endless loop, for i == SIZE_MAX
, the condition is SIZE_MAX<=SIZE_MAX
, which is true and then i
wrap around to 0
and so it goes on.
You are invoking undefined behavior by accessing the vector
out of bounds. Probably the compiler optimises this away and so you simply count to SIZE_MAX
again and again.
As the others have mentioned, size()
is of type size_t
which is unsigned, so size() - n
potentially underflows for all non-zero n
.
Because of this underflow, the loop will execute at least once.
With i
equal to zero and pos.size()
equal to 1, the indexing of pos[i+1]
is undefined behaviour which may segfault:
else if(len<(pos[i]-pos[i+1]))
len=pos[i]-abs(pos[i+1]);
pos
is a vector so often there will be more allocated that the size, so it might not segfault until i
grows to be equal to the initial allocation size of the vector; when this happens the indexing of pos[i+1]
is off the end of the memory allocated for the vector.
It's also possible it doesn't even segfault then, but at the next page boundary - once you have undefined behaviour then it's hard to tell exactly when a program crashes without debugging it or adding trace output, and it really doesn't matter that much either, as you should correct the code instead.
size()
returns an unsigned size_t
. When size is 1, size -2 is a negative number which wraps round to a large posisibe number. Your for loop therefore executes when it shouldn't.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.