Thread: Segmentation Fault 11, Looking for a layman's terms explanation

  1. #1
    Registered User
    Join Date
    Jan 2012
    Location
    Michigan
    Posts
    7

    Segmentation Fault 11, Looking for a layman's terms explanation

    So I finally finished up my first "real" C++ program which was trying to solve Problem 3 from Project Euler. It runs as expected except for when large values are entered. If I enter a value such as 1234567, I get a Segmentation Fault: 11. My guess is it has something to do with an overflow of memory or something, but I have no idea how to track it down, and the tutorial here was well over my head. Being very new to compiled languages, I am still learning all of the terminology and nuances as compared to my first language, MATLAB. Any help on the segmentation fault, as well as general comments about style or other tips you may have for a new C++ programmer would be greatly appreciated! If you do make any comments, please try to keep them "in English" for me. I plan to get there with the terminology, but it's a lot to learn.

    Also, if any efficiency problems are pointed out, do me a favor and just address the loop or segment of code that can be optimized. I like the challenge of figuring out the optimization, and I know this code is not even close to fully optimized, just not sure where to start.

    Thanks in advance!

    Code:
    //============================================================================
    // Name        : Problem_03.cpp
    // Author      : Stefano Prezioso
    // Version     :
    // Copyright   : 
    // Description : Project Euler Problem 3
    //============================================================================
    
    
    #include <iostream>
    #include <math.h>
    #include <cmath>
    
    
    using namespace std;
    
    
    int main() {
        //Declare variables
        int counter = 0;
    
    
        double value, quotient = 0;
    
    
        //Declare value to find the largest prime value of
        //Goal Value is 600851475143
        cout<< "Enter a value: "; cin>>value;
        cin.ignore();
    
    
        //Calculate iVal for efficiency of following for loops
        int iVal = value/2 +1;
    
    
        //Declare array. Can I make this a static array while still using the value of halfVal somehow? I don't need a dynamic allocation of memory.
        double factors[iVal];
    
    
        //Determine the quotient of the value divided by num (from 2 to iVal) for logical test
        for (double num = 1; num < iVal; num = num + 2) {
    
    
            quotient = (value / num);
    
    
            //Print equation to calculate quotient in each iteration
            //cout << value << " / " << num << " = " << quotient << "\n";
    
    
            //Logical test to determine whether or not num is a factor. If so, store in factors array and update counter
            if (quotient == floor(quotient)) {
                factors[counter] = num;
                counter = counter + 1;
            }
        }
    
    
        //        //Print Factors of Value
        //        for (int i = 0; i < counter; i++) {
        //
        //            cout << "Factor: " << factors[i] <<"\n";
        //        }
    
    
        int numFactors = counter;
    
    
        //printf("Counter: %i\n", counter);
    
    
        double subValues[iVal];
    
    
        counter = 0;
    
    
        quotient = 0;
    
    
        double primeFactors[iVal];
    
    
        double i;
        int j;
    
    
        //Determine which factor to analyze
        for (int position = 0; position < numFactors; position++) {
    
    
            //printf("Factor being tested: %.0f\n", factors[position]);
    
    
            //Builds array subValues with possible factors of factor
            for (i = 1, j = 0; i < (factors[position] + 1); i++, j++) {
    
    
                subValues[j] = i;
    
    
                //printf("Subvalue: %.0f\nj: %i\n", subValues[j], j);
            }
    
    
            int flag = 0;
    
    
            //Divide current factor n by all values from 2 to n-1 to determine primeness
            for (int k = 1; k < factors[position] - 1; k++) {
    
    
                //printf("Evaluated Factor: %.0f\n", factors[position]);
    
    
                double currentVal = factors[position];
    
    
                quotient = currentVal / subValues[k];
    
    
                //printf("k Value: %i\nsubValues[k] Value: %f\nQuotient: %.2f\n", k, subValues[k], quotient);
    
    
                double roundedQuotient = ceil(quotient);
    
    
                //Flag non-prime numbers
                if (quotient == roundedQuotient) {
    
    
                    flag = 1;
    
    
                }
            }
            //Store prime factors in array
            if (flag == 0) {
    
    
    //            printf("Factors[position]: %.0f\n", factors[position]);
    
    
    //            printf("counter: %i\n", counter);
    
    
                primeFactors[counter] = factors[position];
    
    
                counter = counter + 1;
            }
        }
    
    
        printf("Value is: %.0f\n", value);
    
    
    //    printf("Number of factors: %i\n", numFactors);
    
    
        printf("Number of Prime Factors: %i\n", counter);
    
    
        printf("Largest prime factor is: %.0f\n", primeFactors[counter - 1]);
    
    
        cout<< "Press enter to end program.";
    
    
        cin.get();
    }

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    First off,
    >>double factors[iVal];
    this is non-standard. While some compilers may happily accept it, it's wrong.

    Change it to std::vector<double> factors(iVal) instead. Same for the others.
    The problem is that you are smashing the stack with high values. The stack is limited to around 1 MB memory or so.
    If you want more, then you need to go dynamic.

    The good news is that vector does this for you. And you don't need to do anything else than change it into a vector. No cleanup whatsoever.

    Oh yes, and change printf to cout.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Novice
    Join Date
    Jul 2009
    Posts
    568
    (1) Get it to work, and then you can start thinking about optimisation.
    (2) Include `<limits>` and do `std::cout << "Largest value that can be stored by type int = " << std::numeric_limits<int>::max() << std::endl;` and consider the output in the light of what you're trying to do.
    (3) Do not mix `std::cout` and `printf()`. It leads to breakage.
    (4) Compact and reorganize your code to achieve logical grouping. Otherwise your code is near-impossible to read.
    Disclaimer: This post shows my ignorance at the time of its making. I claim ownership of but not responsibility for all errors in it. Reference at your own peril.

  4. #4
    Registered User
    Join Date
    Jan 2012
    Location
    Michigan
    Posts
    7
    Quote Originally Posted by msh View Post
    (2) Include `<limits>` and do `std::cout << "Largest value that can be stored by type int = " << std::numeric_limits<int>::max() << std::endl;` and consider the output in the light of what you're trying to do.
    Alright, so my goal value is greater than the max value of the int data type. It should still be within the limits of the double data type, right? Is this causing an issue with iVal? The contraints of the different data types are something I am still learning. Any clarification would be greatly appreciated.

    Quote Originally Posted by msh View Post
    (4) Compact and reorganize your code to achieve logical grouping. Otherwise your code is near-impossible to read.
    I'm all for trying to make my code clear and readable! Can you be more specific with what you mean by this? Since I'm new to this, I'm not sure what you mean by logical grouping.

  5. #5
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    I don't need a dynamic allocation of memory
    Oh yes you do, you are asking for user input and then using this 'arbritrary' value (iVal) to determine the size of your storage, your compiler feels much pain when this occurs, C++ offers a keyword to help with this, as well as the powerful standard template library which has a variety of 'container' classes like as Elysia pointed out, 'vector' that let you manage this requirement, and bonus, they come off the shelf with lots of easy, built in functiionality that will twist your melon goodstyle. (Ok, Elysia didnt quite say it would twist your melon, its good nevertheless)
    Your present method if you compiled it succesfully would still be hindered by the stack allocation, which is a lot less than whatt most platforms could potentially offer.
    Conversely dynamic methods wil only be limited by system spec.

    Why don't you think you need dynamic memory? Is the maximum possible storage you are supporting known? in which case just declare it as fixed allocation and handle any larger user-supplied value (or result of value..as a good whole number...) with your general input validation
    Unless of course the maximum storage you want to define is is too big for the stack anyway, in which case just write a one-off allocation.
    Last edited by rogster001; 02-03-2012 at 05:15 PM.
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  6. #6
    Registered User
    Join Date
    Jan 2012
    Location
    Michigan
    Posts
    7
    Yeah, I realize I do now! That was an old comment from when I had everything done in predetermined values. I've implemented std::vector and it works great! I'm now running into a different issue when I push to even larger numbers, and getting an error that says, "terminate called throwing an exceptionAbort trap: 6". My guess is that I am requiring more memory than the stack allows, but I'm not sure how to get more memory through allocation. Any tips?

  7. #7
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by StefPrez View Post
    Alright, so my goal value is greater than the max value of the int data type. It should still be within the limits of the double data type, right? Is this causing an issue with iVal? The contraints of the different data types are something I am still learning. Any clarification would be greatly appreciated.
    Stick with integer types to avoid floating-point type weirdness. See if your compiler supports `long long` type which, if available, should be big enough. Otherwise you'll have to use GMP or another arbitrary precision library.

    Quote Originally Posted by StefPrez View Post
    I'm all for trying to make my code clear and readable! Can you be more specific with what you mean by this? Since I'm new to this, I'm not sure what you mean by logical grouping.
    Lines of code that belongs together should be formatted so. Right now all your code is evenly spaced which makes it hard to grasp the overall structure of it. Imagine how hard it would be to follow a novel if every sentence started on a new line with a blank line in between.

    Your primality test is also very naive. You're basically brute-forcing your way through the problem. Consider looking into one of the more sophisticated primality algorithms and implementing one you fell you could handle. A lot of PE problems have to do with primes, and having a piece of code you can reuse whenever that particular problem comes up is a Good Thing.
    Disclaimer: This post shows my ignorance at the time of its making. I claim ownership of but not responsibility for all errors in it. Reference at your own peril.

  8. #8
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    My guess is that I am requiring more memory than the stack allows, but I'm not sure how to get more memory through allocation. Any tips?
    You need to post a little code to show how you have changed things to include vector.

    The vector object allwos you to clear it down, resize as required etc, so really you need to clarify with code. When you refere to 'big' numbers do you mean the values you are storing or the memory requested?
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Or rather than code, you could always use one of those giant lists of primes available elseweb to see if some number is prime or not.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation Fault
    By seanfmglobal in forum C Programming
    Replies: 4
    Last Post: 12-22-2011, 01:31 PM
  2. arg SEGMENTATION FAULT!
    By rocomotion in forum C Programming
    Replies: 2
    Last Post: 09-23-2009, 06:27 AM
  3. Lex help - Segmentation Fault
    By gunner_uk2000 in forum C Programming
    Replies: 2
    Last Post: 11-02-2005, 11:20 AM
  4. Segmentation Fault
    By jat421 in forum C Programming
    Replies: 6
    Last Post: 04-03-2005, 02:26 PM
  5. segmentation fault and memory fault
    By Unregistered in forum C Programming
    Replies: 12
    Last Post: 04-02-2002, 11:09 PM