I's running this on visual c++ and it runs without error. However, when I tried to run this on Linux, it kept giving me this "segmentation fault" message without any output. There is no pointer and is a quite simple program so can anyone please tell me what is wrong??

here's the program!

#include <iostream>
#include <string>
#include <cassert>
using namespace std;

int positionOfMax(const string a[], int n)
{
    if (n <= 0)
        return -1;

    if (myStrlen(a) == 0)
        return -1;

    string max = "";
    int i = 0;
    int keep;
    while (i < n)
    {
        if (max < a[i])
        {
            max = a[i];
            keep = i;
        }
        i++;
    }

    return keep;

}

int rotateLeft(string a[], int n, int pos)
{
    if(n <= 0 || pos > n || pos < 0)
        return -1;

    string save = a[pos];
    int returnValue = pos;
    while((n-1) > pos)
    {
        a[pos] = a[pos + 1];
        pos ++;
    }
    a[pos] = save;
    return returnValue;
}

int partition(string a[], int n, string separator)
{
    if (n <= 0)
        return -1;

    int i = n;
    while (i > 0)
    {
        int pos = positionOfMax(a, i); //find the latest one's position
        rotateLeft(a, i, pos); //move the latest one to the end
        i--;
        pos = 0;
    }


    int start = 0;
    while (start < n)
    {
        if (separator > a[start])
            start++;
        else
            return start;
    }

    return n;

}

int main()
{
    string folks[6] = { "obiwan", "minnie", "han", "simba", "jabba", "ariel" };
    assert(partition(folks, 6, "base") == 1); //return 1 since only the first one “ariel” is less than base

    cerr << "Test ok" << endl;
}

The problem is that you are taking the size of the array as the highest index:

    int i = n;
    while (i > 0)
    {
        int pos = positionOfMax(a, i); //find the latest one's position
        rotateLeft(a, i, pos); //move the latest one to the end
        i--;
        pos = 0;
    }

Arrays in C++ are zero-indexed, meaning that for an array of size 6, the indices would be 0, 1, 2, 3, 4, and 5. An index number of 6 will go off the end of the array, causing the segfault. You'll want to change this to

    int i = n - 1;
    while (i >= 0)
    {
        int pos = positionOfMax(a, i); //find the latest one's position
        rotateLeft(a, i, pos); //move the latest one to the end
        i--;
        pos = 0;
    }

Since you seem to make this mistake throughout the code, you'll need to make similar changes across the whole program, I'm afraid.

As for why it doesn't fail in Windows (it should), I'm guessing that it is silently trashing some otherwise unimportant piece of data on main()'s stack area.

BTW, where is myStrlen() declared?

Edited 4 Years Ago by Schol-R-LEA

oooops sorry i forgot to include that here ._.

int myStrlen(const string c[])
{
    int count = 0;
    for(; c[count] != "\0"; count++);
    return count;
}

umm i understand what you're saying but if I make i less than n, i would never call the function a[i] that's not in the scope right?
and i should probably explain the function :p
int partition(string a[], int n, string separator) // you take the string a and take the first n number of element. place them in the order so that every element that is less than the separator is before the ones that are more than the separator. that's why in int main it should be equal to 1.If I change the program into your example, I would get a return 0 instead :(

And the thing is that when i just test the other two dunctions, everything works fine! WUTS GOING ONNNNN :(((((

OK, I'm more confused than ever, especially with regards to the myStrlen() function. First off, it is getting the size of the array of strings, not any one string itself, so the name is misleading. More to the point, it relies on there being a string at the end of the array consisting of a single null value. But this won't be the case for an array of C++ strings, not without there being an explicit marker! Whe I tested this, it showed that it was indeed going off the array:

int main()
{
    string folks[6] = { "obiwan", "minnie", "han", "simba", "jabba", "ariel" };
    cerr << myStrlen(folks) << endl << endl;
    assert(myStrlen(folks) == 6);
    cerr << "myStrlen() - Test ok" << endl << endl;

    assert(partition(folks, 6, "base") == 1); //return 1 since only the first one “ariel” is less than base

    cerr << "partition() - Test ok" << endl;
}

When I ran it after compiling with MinGW gcc 4.6, the actual size returned by myStrlen() was 9, which means that it was continuing on past the end of the array until it found something that matched the end condition by sheer chance. Similarly, the returned value was 10 when compiled under VC++ Express 2010.

Edited 4 Years Ago by Schol-R-LEA

ohhhh so maybe this is how i got the segmentation fault from ? cuhz I use this in one of the function :p I was tyring to count the number of elements in the array but now that I know it doesn't work! Is it still possible to point out an array that's empty tho? so I'll be able to return -1 for positionofMax function

EVERYTHING WORKS FINE AFTER I CHANGED THAT MYSTRLN THING!

here's the program :D

int positionOfMax(const string a[], int n)
{
    if (n <= 0)
        return -1;

    for (int i = 0; i < n; i++)
    {
        if (a[i] != "")
            break;
        if ((i == n -1) && a[i] == "")
            return -1;
    }

    string max = "";
    int i = 0;
    int keep;
    while (i < n)
    {
        if (max < a[i])
        {
            max = a[i];
            keep = i;
        }
        i++;
    }

    return keep;

}

I took the mystrln function out and insert another one that looks kinda tedious but everything works fine now!
The length function was the problem! I know that Im not supposed to do that anymore, since there's no way to no the size of the array :)

THANK YOU SOOOOOOO MUCHHHHHH!!!!!!!!!!!

This article has been dead for over six months. Start a new discussion instead.