Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking for Null Pointer not working in C (Giving SegFault Error)

So I'm checking for NULL pointer/Empty string and returning 0 if either are found. However, I seem to be getting a Segmentation Fault error in one of the compilers. If someone could help me figure out what could possibly be causing it. Apparently when empty strings and null pointers are used as input the error comes up. However, this error is not coming up in the compiler that I am using, but is coming up in another compiler (one that I am being graded on).

rpsls.c

#include <string.h>

int rpsls(const char *player1, const char *player2)
{

    if (*player1 == '\0' || *player2 == '\0' || player1 == NULL || player2 == NULL || strcmp(player1, player2) == 0)
        return 0;

    char *r = "rock";
    char *p = "paper";
    char *si = "scissors";
    char *l = "lizard";
    char *s = "Spock";



    if (!strcmp(player1, r) && !strcmp(player2, si))
        return 1;
    else if (!strcmp(player1, p) && !strcmp(player2, r))
        return 1;
    else if (!strcmp(player1, si) && !strcmp(player2, p))
        return 1;
    else if (!strcmp(player1, l) && !strcmp(player2, s))
        return 1;
    else if (!strcmp(player1, s) && !strcmp(player2, si))
        return 1;
    else if (!strcmp(player1, r) && !strcmp(player2, l))
        return 1;
    else if (!strcmp(player1, p) && !strcmp(player2, s))
        return 1;
    else if (!strcmp(player1, si) && !strcmp(player2, l))
        return 1;
    else if (!strcmp(player1, l) && !strcmp(player2, p))
        return 1;
    else if (!strcmp(player1, s) && !strcmp(player2, r))
        return 1;

    if (!strcmp(player2, r) && !strcmp(player1, si))
        return -1;
    else if (!strcmp(player2, p) && !strcmp(player1, r))
        return -1;
    else if (!strcmp(player2, si) && !strcmp(player1, p))
        return -1;
    else if (!strcmp(player2, l) && !strcmp(player1, s))
        return -1;
    else if (!strcmp(player2, s) && !strcmp(player1, si))
        return -1;
    else if (!strcmp(player2, r) && !strcmp(player1, l))
        return -1;
    else if (!strcmp(player2, p) && !strcmp(player1, s))
        return -1;
    else if (!strcmp(player2, si) && !strcmp(player1, l))
        return -1;
    else if (!strcmp(player2, l) && !strcmp(player1, p))
        return -1;
    else if (!strcmp(player2, s) && !strcmp(player1, r))
        return -1;

    return 0;

}

main.c

#include <stdio.h>

int rpsls(const char *player1, const char *player2);

int main (void)
{
  printf ("%d\n", rpsls("rock","paper"));
  printf ("%d\n", rpsls("rock","rock"));
  printf ("%d\n", rpsls("paper","rock"));
  printf ("%d\n", rpsls("lizard",(char*)0));
  printf ("%d\n", rpsls("",(char*)0));

  return 0;
}
like image 894
Maaz Avatar asked Mar 20 '26 02:03

Maaz


1 Answers

Expressions are evaluated left to right with the logical OR operator so in

if (*player1 == '\0' || *player2 == '\0' ||
    player1 == NULL || player2 == NULL ||
    strcmp(player1, player2) == 0)

you dereference NULL in *player1 == '\0' before testing player1 == NULL.

*player1==NULL is equivalent to player1[0]==NULL. If player1 points to memory you didn't allocate, the effects of trying to read this memory are undefined. Anything can happen at this point. In your local tests, you report that this appears to work (I'm sceptical about this); in your teacher's tests, your program doesn't have permission to read address 0 and segfaults.

You need to reorder the expressions

if (player1 == NULL || *player1 == '\0' ||
    player2 == NULL || *player2 == '\0' ||
    strcmp(player1, player2) == 0)
like image 164
simonc Avatar answered Mar 25 '26 02:03

simonc