检查空指针在 C 中不起作用(给出 SegFault 错误)



所以我正在检查 NULL 指针/空字符串,如果找到任何一个,则返回 0。但是,我似乎在其中一个编译器中遇到了Segmentation Fault错误。如果有人能帮我弄清楚可能导致它的原因。显然,当empty stringsnull pointers用作输入时,会出现错误。但是,此错误不会出现在我正在使用的编译器中,而是出现在另一个编译器(我正在评分的编译器)中。

rpsls.c

#include <string.h>
int rpsls(const char *player1, const char *player2)
{
    if (*player1 == '' || *player2 == '' || 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 ("%dn", rpsls("rock","paper"));
  printf ("%dn", rpsls("rock","rock"));
  printf ("%dn", rpsls("paper","rock"));
  printf ("%dn", rpsls("lizard",(char*)0));
  printf ("%dn", rpsls("",(char*)0));
  return 0;
}

表达式使用逻辑 OR 运算符从左到右计算,因此

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

在测试player1 == NULL之前,您在*player1 == ''中取消引用NULL

*player1==NULL相当于player1[0]==NULL。 如果player1指向未分配的内存,则尝试读取此内存的效果是不确定的。 此时任何事情都可能发生。 在您的本地测试中,您报告这似乎有效(我对此持怀疑态度);在教师的测试中,程序无权读取地址0和段错误。

您需要对表达式重新排序

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

在检查 NULL 之前取消引用指针。 有点违背了 NULL 检查的目的。

首先检查 NULL,然后取消引用。

最新更新