views:

313

answers:

2

In this code, for vector size, n >=32767, it gives segmentation fault, but upto 32766, it runs fine. What could be the error? This is full code.

#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<utility>
#include<algorithm>
#include<sys/time.h>
using namespace std;
#define MAX 100000

bool compare(pair<int,int> p1,pair<int,int> p2) {
    if(p1.second < p2.second)
     return 1;
    else if(p1.second > p2.second)
     return 0;
    if(p1.first <= p2.first)
     return 1;
    else
     return 0;
}

int main() {
    freopen("randomin.txt","r",stdin);
    int n;
    scanf("%d",&n);
    vector< pair<int,int> > p(n);
    for(int i=0;i<n;i++)
     scanf("%d%d",&p[i].first,&p[i].second);
    **printf("%d\n",(int)p.max_size()); // prints 536870911**
    sort(p.begin(),p.begin()+n,compare);

    //for(int i=0;i<n;i++)
     //printf("%d %d\n",p[i].first,p[i].second);
        printf("%.6f\n",(p[n-1].second+p[n-2].second)/(20.0+p[n-1].first+p[n-2].first));

    return 0;
}
+3  A: 

Try using all the values from n = 32766 up to 32770. I suspect you'll find that you are experiencing some sort of overflow. This is because 2^15 (32768) is the biggest number that can be represented using 16 bits (assuming you also allow negative numbers). You will have to use a different data type.

Suggestion:

Get it to output the vector's maxsize:

cout << p.max_size();

Let us know what that does. All things being normal, I'd expect it to be in the hundreds of millions (536870911 on my computer). But if it's more like 32768, then that could be the problem.

Smashery
How could there be overflow? I am just comparing. There is no arithmetic being performed here.
avd
Maybe your compiler is setting int to 16 bits ?
Andrew Keith
I am sure that on my system, int is 32 bits. I have checked it
avd
Its GNU g++ on netbeans with cygwin
avd
Your comparison function should return false on equality, not true. Not sure why this should cause a segv...
Keith Randall
I'm not saying "It is overflow." But if you try setting n to those few values, and it works up to about 32768, then you can be pretty sure it's some sort of overflow. At least try those values, and if I'm wrong, then awesome, we can rule out one suggestion. I've just added a bit of extra info in my response, try that.
Smashery
compare function returns 1 or 0 anyways. How can this generate fault?
avd
@Smashery: Yes,u r right. it generates fault for 32767. For 32766, it runs fine.But why this problem has arisen. I m using g++
avd
@aditya: What does p.max_size() give you?
Smashery
aditya, Keith has a point. for n = 350000 where each pair is (0,0) program crashes. after adding if(p1==p2) return 0; it works fine.
maykeye
@Smashery:Yes, it gives 536870911. Please suggest a solution
avd
@aditya: No solution suggestion yet - just trying to gather data to work out what's going wrong. Have you tried Keith's suggestion (above)?
Smashery
avd
@aditya, always 1 is not not a compararer function.Compare http://codepad.org/s3vvaai5 [works fine]and http://codepad.org/sD7kz0b4 [crashes]
maykeye
@Keith - Good point, but I'd be surprised if it's the real issue. May scramble the sort results, but a segfault? @aditya - to fix it, in compare, change the <= to <.
Steve314
Why it is not a comparer? It just depends on the logic.
avd
@Steve314: Yes, it worked. I places < instead of <=. But why? please explain in detail in a new answer post.
avd
@Keith - OK, I think I believe - wierd.
Steve314
@aditya, Jim Lewis already explained it. Check source code of sort functions for more details.
maykeye
@aditya - that's just Keiths thing done differently. You were violating the expectations that sort has for compare. I'm surprised it segfaults, but...
Steve314
Oops - I've been calling maykeye Keith - sorry.
Steve314
But why it was working for n<=32766? Where can I get source code of sort function. With .h files its just prototype.
avd
avd
@maykeye: when did you become Keith? ;-) @aditya: no worries, mate! Very strange about the 32766 limit
Smashery
+6  A: 

This may be unrelated to your segmentation fault, but...

In C++, your "compare" predicate must be a strict weak ordering. In particular, "compare(X,X)" must return "false" for any X. In your compare function, if both pairs are identical, you hit the test (p1.first <= p2.first) , and return "true". Therefore, this "compare" predicate does not impose a strict weak ordering, and the result of passing it to "sort" is undefined.

Jim Lewis
Sir: Does that mean that that C++ checks implicitly that if two objects are same, it should return false. But why it was working for n<=32766. Sir: u r great. You have again helped me solving a problem.
avd
No deliberate implicit check - just a confused sort algorithm. Different input => differently confused.
Steve314
+1 - nicely spotted! @aditya: Remember that STL compare functions are asking "is the first one less than the second" - not "are they equal".
Smashery
@Aditya: There are all sorts of reasons a non-strictly-conforming C++ program might work on some inputs, and fail on others. Consider the case where the library uses one algorithm for large containers (and dumps core if the strict weak ordering is violated), and uses a simpler (and more tolerant) algorithm for smaller values of N.
Jim Lewis
Perhaps it goes too deep into recursion (for example, because the faulty comparison function messes up the algorithm's worst case guarantees)? I would also like to point out that std::pair already defines comparison operators (except it uses first as the first criterion).
UncleBens