Home > Enterprise >  segmentation fault, c programm
segmentation fault, c programm

Time:02-02

I had to write a program in c as a homework assignment. The program checks if the inputed string is a palindrome. Unfortunately I am getting a segmentation fault error when executing my program.

According to my knowledge segmentation fault means I am accessing memory that does not belong to me.

After some trying I found out, that I get that error "during" the marked scanf function. Please help.

This is the source-code:

#include <stdio.h>
#include <ctype.h>

#define FALSE 0
#define TRUE !FALSE

#define STR_LEN01 1000

unsigned long long fStrLen(unsigned char str[])
{
    unsigned long long strLEN = 0;
    for (unsigned short i = 0; str[i  ]; strLEN  ) {}
    return strLEN;
}

unsigned short fStrComp(unsigned char str01[], unsigned char str02[])
{
    for (unsigned short i = 0; /* EMPTY */ ; i  )
    {
        if ( str01[i] == 0 && str02[i] == 0 ) 
            { return 0; }
        else if ( str01[i] != str02[i] && str02[i] == 0 ) 
            { return 1; }
        else if ( str01[i] != str02[i] && str01[i] == 0 ) 
            { return 2; }
        else if ( str01[i] != str02[i] && str02[i] != 0 && str01[i] != 0) 
            { return 3; }
    }
}
// ret 0 = strings are equal
// ret 1 = string 1 is longer
// ret 2 = string 2 is longer
// ret 3 = strings are not equal

void fStrRev(unsigned char str[])
{
    unsigned short len = fStrLen(str);
    unsigned char helpi, helpj;

    for (unsigned short i = len-1, j = 0; i >= 0; i--, j  )
    {
        helpi = str[i];
        helpj = str[j];

        str[i] = helpj;
        str[j] = helpi;

    }

} // ATTENTION! Inputted string will be reversed!

unsigned short fPalindrome(unsigned char str[]) // TODO
{
    unsigned char rev[STR_LEN01];

    for (unsigned short i = 0; str[i]; i  )
    {
        rev[i] = str[i];
    }
    fStrRev(str);

    return fStrComp(str, rev);   
} 
// ret 0 = palindrome
// *ret 1 = string 1 is longer*
// *ret 2 = string 2 is longer*
// ret 3 = strings are not equal, so no palindrome

int main(void)
{
    unsigned short ret = 0;
    unsigned char strIN01[STR_LEN01], strREV01[STR_LEN01], exit[] = "end";

    while(TRUE)
    {
        printf("\n\n"
                "Your word: ");


        scanf(" %s", strIN01); ***// MARKED SCANF***


        for (unsigned short i = 0; strIN01[i]; i  ) 
        { putchar( tolower( strIN01[i] ) ); }

        if(fStrComp(strIN01, exit) == 0) { return 0; }

        for (unsigned int i = 0; strIN01[i]; i  )
        {
            strREV01[i] = strIN01[i];
        }
        strREV01[ fStrLen(strIN01) ] = 0;
        fStrRev(strREV01);
        printf("word reversed: %s", strREV01);

        ret = fPalindrome(strIN01);

        if(ret == 0)
        {
            printf("Hurray! We have a palindrome :)\r\n");
        }
        else if(ret == 3)
        {
            printf("Unfortunately, your word is no palindrome :(\r\n");
        }
    }

    return 0;
}

This is the Shell error:

   └─$ gcc -Wall palindrom.c -o pal -lm                                                                                
       └─$ ./pal                           


   Your word: hello    
zsh: segmentation fault  ./pal

   └─$ 

Thank you for your help in advance.

Yours Faithfully, Tiger

PS The functions were tested by me separately while programming and should work

CodePudding user response:

the for loop in fStrRev is what's causing you segmentation fault

for (unsigned short i = len-1, j = 0; i >= 0; i--, j  )
{
    helpi = str[i];
    helpj = str[j];

    str[i] = helpj;
    str[j] = helpi;
}

i gets decremented by one each cycle and the cycle continues until i is less than 0, the problem is that when i get decremented from 0 it becomes 65535 instead of -1 as i is an unsigned short causing the for loop to continue and your seg fault when it tries to access str[65535] to fix this just change the for loop from unsigned short to short or another signed integer type if you need the extra range like so.

for (short i = len-1, j = 0; i >= 0; i--, j  )
{
    helpi = str[i];
    helpj = str[j];

    str[i] = helpj;
    str[j] = helpi;
}

There's also another problem with your code as it's not working as intended for reversing the word and reversing it twice, so the comparison should be changed from i >= 0 to i >= len/2 or what Ian Abbott commented if you're going with his solution

CodePudding user response:

Within this function

unsigned short fPalindrome(unsigned char str[]) // TODO
{
    unsigned char rev[STR_LEN01];

    for (unsigned short i = 0; str[i]; i  )
    {
        rev[i] = str[i];
    }
    fStrRev(str);

    return fStrComp(str, rev);   
} 

you are not building a string in the array rev. That is the array does not contain the zero terminating character '\0'.

So calling string functions for this array invokes undefined behavior.

You could rewrite the function at least the following way using a loop

unsigned short fPalindrome( unsigned char str[]) // TODO
{
    unsigned char rev[STR_LEN01];

    unsigned char *p = rev;

    while ( ( *p   = *str   ) != '\0' );

    fStrRev(str);

    return fStrComp(str, rev);   
} 
  •  Tags:  
  • Related