Unexplainable run-time segfault error

This is a discussion on Unexplainable run-time segfault error within the C++ Programming forums, part of the General Programming Boards category; And before you mention it, the "const" keyword was removed from the return value of stripString, the post was edited, ...

  1. #31
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    And before you mention it, the "const" keyword was removed from the return value of stripString, the post was edited, and the new link given.
    I had it like that because it was originally returning a reference, then when I changed it back to return just a string, I forgot to remove the "const" keyword. But that's fixed now.
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  2. #32
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,598
    Here is what I might simplify the first part of your code to:
    Code:
    #include <string>
    #include <cstring>
    #include <cctype>
    #include <iostream>
    #include <cassert>
    
    using namespace std;
    
    enum ET_strippingMode {
        exclusive = 0,
        inclusive = 1
    };
    
    bool searchStringIsSpecialString(const char searchString[]) {
        return strcmp(searchString, "A-Za-z") == 0;
    }
    
    bool sourceStringContainsAlphabetChar(const char sourceString[]) {
        //we are assuming 'sourceString' is pointed at a null-terminated char array...
        unsigned int sourceStringSize = strlen(sourceString);
    
        for (unsigned int i = 0; i < sourceStringSize; i++) {
            if (isalpha(sourceString[i])) {
                return true; //at the first char in the range of A-Z or a-z
            }
        }
    
        return false;
    }
    
    bool containsString(const char sourceString[], const char searchString[]) {
        //assume that 'sourceString' and 'searchString' are pointing at two null-terminated char arrays...
        unsigned int sourceStringSize = strlen(sourceString);
        unsigned int searchStringSize = strlen(searchString);
    
        if (searchStringSize < sourceStringSize) {
            //if the special string "A-Za-z" was passed into the 'searchString' parameter
            //then search for a character in sourceString in the range of A-Z, or a-z,
            //otherwise check to see if the searchString is contained in the sourceString.
            return searchStringIsSpecialString(searchString) && sourceStringContainsAlphabetChar(sourceString)
                || sourceString.find(searchString) != string::npos;
        }
        else if (searchStringSize == sourceStringSize) { //meaning the two strings have the same length
            //if the special string "A-Za-z" was passed into the 'searchString' parameter
            //then search for a character in sourceString in the range of A-Z, or a-z,
            //otherwise check to see if the source string and the search string are the same.
            return searchStringIsSpecialString(searchString) && sourceStringContainsAlphabetChar(sourceString)
                || strcmp(sourceString, searchString) == 0;
        }
    
        //since the string searched for is longer string than the one being checked,
        //there is no possibility of the shorter string fully containing the longer string.
        return false;
    }
    Now, for the stripString function: I suggest that you break it up into two helper functions: one to handle exclusive stripping mode, the other to handle inclusive stripping mode.

    EDIT:
    Oh, and another thing for stripString: instead of nesting a do while loop in a for loop, first use one loop to find the start character, and then use a separate loop for the rest of the parsing.
    Last edited by laserlight; 06-26-2010 at 05:07 PM.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #33
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by laserlight View Post
    Here is what I might simplify the first part of your code to:
    Code:
    #include <string>
    #include <cstring>
    #include <cctype>
    #include <iostream>
    #include <cassert>
    
    using namespace std;
    
    enum ET_strippingMode {
        exclusive = 0,
        inclusive = 1
    };
    
    bool searchStringIsSpecialString(const char searchString[]) {
        return strcmp(searchString, "A-Za-z") == 0;
    }
    
    bool sourceStringContainsAlphabetChar(const char sourceString[]) {
        //we are assuming 'sourceString' is pointed at a null-terminated char array...
        unsigned int sourceStringSize = strlen(sourceString);
    
        for (unsigned int i = 0; i < sourceStringSize; i++) {
            if (isalpha(sourceString[i])) {
                return true; //at the first char in the range of A-Z or a-z
            }
        }
    
        return false;
    }
    Good idea for those two functions. Changed my code to that.
    Code:
    bool containsString(const char sourceString[], const char searchString[]) {
        //assume that 'sourceString' and 'searchString' are pointing at two null-terminated char arrays...
        unsigned int sourceStringSize = strlen(sourceString);
        unsigned int searchStringSize = strlen(searchString);
    
        if (searchStringSize < sourceStringSize) {
            //if the special string "A-Za-z" was passed into the 'searchString' parameter
            //then search for a character in sourceString in the range of A-Z, or a-z,
            //otherwise check to see if the searchString is contained in the sourceString.
            return searchStringIsSpecialString(searchString) && sourceStringContainsAlphabetChar(sourceString)
                || sourceString.find(searchString) != string::npos;
        }
        else if (searchStringSize == sourceStringSize) { //meaning the two strings have the same length
            //if the special string "A-Za-z" was passed into the 'searchString' parameter
            //then search for a character in sourceString in the range of A-Z, or a-z,
            //otherwise check to see if the source string and the search string are the same.
            return searchStringIsSpecialString(searchString) && sourceStringContainsAlphabetChar(sourceString)
                || strcmp(sourceString, searchString) == 0;
        }
        //since the string searched for is longer string than the one being checked,
        //there is no possibility of the shorter string fully containing the longer string.
        return false;
    }
    Thanks. That is a lot cleaner and shorter code. But you should note though that you forgot to handle the case where the searchString is longer than the sourceString, but searchString is the special string. You just automatically assumed it should return false in that case.
    Now, for the stripString function: I suggest that you break it up into two helper functions: one to handle exclusive stripping mode, the other to handle inclusive stripping mode.
    Hmm...I may do that, but I think it would be a ...........
    EDIT:
    Oh, and another thing for stripString: instead of nesting a do while loop in a for loop, first use one loop to find the start character, and then use a separate loop for the rest of the parsing.
    So I guess set a bool var to true for that then? Yeah, that should work...
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  4. #34
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,598
    Taking my own advice, I see that it is simpler than expected:
    Code:
    #include <string>
    #include <cstring>
    #include <cctype>
    #include <iostream>
    #include <stdexcept>
    
    using namespace std;
    
    enum ET_strippingMode {
        exclusive = 0,
        inclusive = 1
    };
    
    bool searchStringIsSpecialString(const char searchString[]) {
        return strcmp(searchString, "A-Za-z") == 0;
    }
    
    bool sourceStringContainsAlphabetChar(const char sourceString[]) {
        //we are assuming 'sourceString' is pointed at a null-terminated char array...
        unsigned int sourceStringSize = strlen(sourceString);
    
        for (unsigned int i = 0; i < sourceStringSize; i++) {
            if (isalpha(sourceString[i])) {
                return true; //at the first char in the range of A-Z or a-z
            }
        }
    
        return false;
    }
    
    bool containsString(const char sourceString[], const char searchString[]) {
        //assume that 'sourceString' and 'searchString' are pointing at two null-terminated char arrays.
    
        //if the special string "A-Za-z" was passed into the 'searchString' parameter
        //then search for a character in sourceString in the range of A-Z, or a-z.
        if (searchStringIsSpecialString(searchString) && sourceStringContainsAlphabetChar(sourceString)) {
            return true;
        }
        else {
            size_t sourceStringSize = strlen(sourceString);
            size_t searchStringSize = strlen(searchString);
            if (searchStringSize < sourceStringSize) {
                //check to see if the searchString is contained in the sourceString.
                return strstr(sourceString, searchString) != NULL;
            }
            else if (searchStringSize == sourceStringSize) {
                //check to see if the source string and the search string are the same.
                return strcmp(sourceString, searchString) == 0;
            }
            else {
                //there is no possibility of the shorter string fully containing the longer string.
                return false;
            }
        }
    }
    
    namespace
    {
        string stripStringExclusive(const char str[], size_t size, const char end, size_t i) {
            string strippedString = "";
            for (; i < size; ++i) {
                if (str[i] == end) {
                    return strippedString;
                }
                else if (str[i] != ' ') { //skip spaces
                    strippedString.push_back(str[i]);
                }
            }
            return ""; //end char is not present
        }
    
        string stripStringInclusive(const char str[], size_t size, const char end, size_t i) {
            string strippedString = "";
            for (; i < size; ++i) {
                if (str[i] == end) {
                    strippedString.push_back(end);
                    return strippedString;
                }
                else if (str[i] != ' ') { //skip spaces
                    strippedString.push_back(str[i]);
                }
            }
            return ""; //end char is not present
        }
    }
    
    string stripString(const char str[], const char start, const char end, ET_strippingMode strippingMode = exclusive) {
        char* start_ptr = strchr(str, start);
        if (start_ptr == NULL) {
            return "";
        }
    
        if (strippingMode == exclusive) {
            return stripStringExclusive(str, strlen(str), end, str - start_ptr + 1);
        }
        else if (strippingMode == inclusive) {
            return stripStringInclusive(str, strlen(str), end, str - start_ptr);
        }
        else {
            throw invalid_argument("stripping mode must be either exclusive or inclusive");
        }
    }
    
    int main() {
        char filestreamInBuffer[] = "enum DAY {";
        if (containsString(filestreamInBuffer, "enum")) {
            cout<< "Yes, \"" << filestreamInBuffer << "\" does indeed contain \"enum\"." <<endl;
        }
        else {
            cout<< "No, \"" << filestreamInBuffer << "\" does not contain \"enum\"." <<endl;
        }
    
        if (containsString(filestreamInBuffer, ";")) {
            cout<< "Yes, \"" << filestreamInBuffer << "\" does indeed contain \";\"." <<endl;
        }
        else {
            cout<< "No, \"" << filestreamInBuffer << "\" does not contain \";\"." <<endl;
        }
    
        string currentEnumName = stripString(filestreamInBuffer, 'm', '{');
        cout<< "The name of the current enum is: " << currentEnumName <<endl;
    
        return 0;
    }
    Last edited by laserlight; 06-26-2010 at 05:54 PM. Reason: return false -> return ""
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #35
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Your code didn't output the stripped string...

    http://codepad.org/uCWA3Ttd
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  6. #36
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by laserlight View Post
    That is expected since the end character is not present in your test string.
    Umm...actually, it is:

    Code:
    char filestreamInBuffer[] = "enum DAY {";
    //...do stuff
    string currentEnumName = stripString(filestreamInBuffer, 'm', '{');
    And anyway, I wanted the stripString function to return the strippedString even if the end char was not found (I have my reasons). Only if the start char was not found, was the function supposed to return nothing.
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  7. #37
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,598
    Right. What is stripString supposed to do?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #38
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by laserlight View Post
    Right. What is stripString supposed to do?
    It is supposed to strip the sourceString from the start char to the end char if the end char is present, otherwise it should strip it until the end of the sourceString.
    If the stripping mode is exclusive, it should exclude the start and end chars. Otherwise, if its inclusive, it should include them.

    EDIT: Also, I wanted the function to return a completely different string than the one passed. I didn't want it to modify the original string by way of a reference or a pointer passed in its parameter.
    Last edited by Programmer_P; 06-26-2010 at 06:12 PM. Reason: thought of something
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  9. #39
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,598
    What do you mean by "strip the sourceString"?

    What my implementation does is that it extracts the characters from start to end, ignoring spaces. If it is inclusive, the start and end chars are extracted, otherwise they are not.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #40
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by laserlight View Post
    What do you mean by "strip the sourceString"?
    Return a stripped string containing chars from start to end (if exclusive). If its in inclusive mode, than the stripped string should contain also the start and end chars.
    What my implementation does is that it extracts the characters from start to end, ignoring spaces. If it is inclusive, the start and end chars are extracted, otherwise they are not.
    No, it doesn't, because it obviously doesn't work, since it returns nothing, even though both the start and end chars are present in the string passed.
    Looking at your description, I would expect only a space to be extracted, since that is the only thing in between 'm' and '{'.
    Actually, its not: The other thing is the string "DAY".
    Last edited by Programmer_P; 06-26-2010 at 06:19 PM.
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  11. #41
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,598
    Grr... logic error: in stripString, subtract str from start_ptr, not the other way around. I'll leave the change to "strip it until the end of the sourceString" up to you.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #42
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,299
    Quote Originally Posted by Programmer_P View Post
    Yes, I know, but I figure my method is more clearer when you're looking at the code.
    Anyway, none of this has anything to do with a if(false) statement being entered. So far, no one has commented on this...
    It's not clearer...

    Do you say to someone:
    Is <some number> squared equal to nine?
    or
    Answer me "yes" if <some number> squared is equal to nine, otherwise answer me "no"?
    or
    If you would answer "yes" to "Answer 'yes' if <some number> squared is equal to nine, otherwise answer me 'no'" then answer "yes", otherwise answer "no"?

    If you start comparing boolean expressions to true, where are you supposed to draw the line?:
    Code:
    if (x*x - 9)					//slightly obfuscated (taking things a bit too far)
    if (x*x == 9)					//perfect
    if ((x*x == 9) == true)				//barely acceptable
    if (((x*x == 9) == true) == true)		//very bad
    if ((((x*x == 9) == true) == true) == true)	//insanely ridiculous
    Forgetting that this is a crap example for a moment...
    A few people code with a style equivalent to the first or third line above, but most people code in such as style as the second line. The level of redundancy you're coding to puts your code on par with the fourth line!
    Last edited by iMalc; 06-26-2010 at 11:22 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #43
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Code:
    char* start_ptr = strchr(str, start);
    Why does the strchr function want a int type passed into its second parameter, and why does passing a char into it work without any compiler error?

    @laserlight: Btw, I got your code to work:
    C++ code - 124 lines - codepad
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  14. #44
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Programmer_P View Post
    Why does the strchr function want a int type passed into its second parameter,
    Possibly to work with EOF which is not a char? Anyway, many C string functions are like this -- the trend is to favour more inclusive and generic types, I think.

    and why does passing a char into it work without any compiler error?
    It will generate a warning probably, if you have warnings enabled. Just cast (int).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #45
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,485
    They pre-date ANSI C (and prototypes). In the K&R world, all parameters tended to get promoted to int or double, unless expicitly cast.

    Variadic parameters for the likes of printf etc still follow default promotion rules.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Page 3 of 4 FirstFirst 1234 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. file reading
    By gunghomiller in forum C++ Programming
    Replies: 9
    Last Post: 08-07-2007, 10:55 PM
  2. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 01:53 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. ras.h errors
    By Trent_Easton in forum Windows Programming
    Replies: 8
    Last Post: 07-15-2005, 10:52 PM
  5. Linking error
    By DockyD in forum C++ Programming
    Replies: 10
    Last Post: 01-20-2003, 04:27 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21