shoe
shoe

Reputation: 21

iterator segmentation fault c++

I wrote a simple algorithm to display the nth prime. Simply put, it uses a vector of found primes to check if the next number is prime as well; if it is, it pushes it into the vector and repeats until the nth prime is found.

Unfortunately, I am getting a segmentation fault in the for loop nested in the while loop and I have no idea why. More specifically, the error occurs in the header of the for loop; I added a cerr << "Check " << z++ << endl; to the body of the for loop (and one before it altogether) to see where it occurred so I believe the error is related to the iterators.

The program is very small and I don't mind sharing it (if you have a use for it have at it) so here's the whole thing:

#include <iostream>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <vector>

using std::cout;
using std::cerr;
using std::endl;
using std::vector;

int main( int argc, char* argv[] )
{
    if( argc != 2 )
    {
        cerr << "USAGE: nthPrime n" << endl;
        return 1;
    }

    vector< unsigned > primes;
    vector< unsigned >::iterator it;
    bool isPrime;
    char *sffx = ( char ) 0;
    unsigned n = atoi( argv[ 1 ] ),
             x = 3,
             max;

    primes.push_back( 2 );

    while( primes.size() != n )
    {
        isPrime = true;
        max = ( unsigned )sqrt( x );

        for( it = primes.begin(); *it <= max; ++it )
            if( !( x % *it ) ) isPrime = false;

        if( isPrime ) primes.push_back( x );
        x += 2;
    }

    if( n == 1 ) strcpy( sffx, "st" );
    else if( n == 2 ) strcpy( sffx, "nd" );
    else if( n == 3 ) strcpy( sffx, "rd" );
    else strcpy( sffx, "th" );

    cout << "The " << n << sffx << " prime is " << primes.back() << endl;

    return 0;
}

Here's the makefile too for convienience:

CCFLAGS = -Wall -std=c++11

nthPrime: nthPrime.o
    g++ $(CCFLAGS) -o nthPrime nthPrime.o

nthPrime.o: nthPrime.cpp
    g++ $(CCFLAGS) -c nthPrime.cpp

clean:
    -rm *.o nthPrime

I have neglected to add any comments as I just wrote it an hour ago so please let me know if you would like me to.

Thanks in advance.

P.S. I have tried adding && it != primes.end() to the for loop but it shouldn't be required due to the properties of the algorithm and it didn't help anyway.

Upvotes: 2

Views: 660

Answers (2)

shoe
shoe

Reputation: 21

Ok thank you everyone for getting back to me so quickly! I thought I'd be waiting all day! The issue turned out to be the line char *sffx = ( char ) 0;. Changing it to char *sffx = new char[ 3 ]; fixed everything.

For anyone who may end up having a similar issue or just wants the program for whatever reason, here it is:

#include <iostream>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <vector>

using std::cout;
using std::cerr;
using std::endl;
using std::vector;

int main( int argc, char* argv[] )
{

    vector< unsigned > primes;
    vector< unsigned >::iterator it;
    bool isPrime;
    char *sffx = new char[ 3 ];
    unsigned n = atoi( argv[ 1 ] ),
             x = 3,
             max;

    if( argc != 2 || n < 1)
    {
        cerr << "USAGE: nthPrime n>0" << endl;
        return 1;
    }

    primes.push_back( 2 );

    while( primes.size() < n )
    {
        isPrime = true;
        max = ( unsigned )sqrt( x );

        for( it = primes.begin(); *it <= max; ++it )
            if( !( x % *it ) ) isPrime = false;

        if( isPrime ) primes.push_back( x );
        x += 2;
    }

    if( n % 10 == 1 && n % 100 != 11 ) strcpy( sffx, "st" );
    else if( n % 10 == 2 && n % 100 != 12 ) strcpy( sffx, "nd" );
    else if( n % 10 == 3 && n % 100 != 13 ) strcpy( sffx, "rd" );
    else strcpy( sffx, "th" );

    cout << "The " << n << sffx << " prime is " << primes.back() << endl;

    return 0;
}

Enjoy and thank you all again!

P.S. the 86626th prime is a cool one I just ran into randomly to test the program at a high value; check it out!

Upvotes: 0

didiz
didiz

Reputation: 1099

Some issues I can see:

1) using argv without checking

unsigned n = atoi( argv[ 1 ] ),
             x = 3,
             max;

2) This:

char *sffx = ( char ) 0;

Does not allocate space for this:

if( n == 1 ) strcpy( sffx, "st" );
else if( n == 2 ) strcpy( sffx, "nd" );
else if( n == 3 ) strcpy( sffx, "rd" );
else strcpy( sffx, "th" );

Upvotes: 2

Related Questions