Maaz
Maaz

Reputation: 4303

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;
}

Upvotes: 2

Views: 3825

Answers (2)

simonc
simonc

Reputation: 42215

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)

Upvotes: 6

Ed Swangren
Ed Swangren

Reputation: 124790

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

You're dereferencing the pointers before checking for NULL. Kind of defeats the purpose of the NULL check.

Check for NULL first, then dereference.

Upvotes: 3

Related Questions