Reputation: 4303
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
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
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