segmentation fault
。
实际上,我用C语言写了一个战舰网络游戏(这是一个学生项目)。我有一个名为Player
:的结构
enum state{PLAYING = 0, WINNER = 1, LOOSER = 2};
enum action{ATTACK = 1, WAIT = 0, NOTHING = -1};
typedef struct Player Player;
struct Player
{
enum action action;
enum state state;
char name[25];
int isFirstPlayer;
Client* client;
Server* server;
Boards* boards;
};
主要功能。
int main(int argc, char *argv[])
{
if(argc < 2)
{
errorUsage();
}
// Initialise player
Player player = newPlayer();
// I removed the network initialization here.
// play game
play_game(&player);
}
segmentation fault
出现在函数play_game(Player* p)
:中
void attack(Player* p)
{
char msg[2];
bzero(msg, strlen(msg));
printf("Where do you want to fire?");
scanf("%s", msg);
while(verifyEntryAttack(msg) != 1)
{
printf("ERROR Entry:nFormat = A4, C9, ...nColumns = A B C D E F G H I JnRows = 0 1 2 3 4 5 6 7 8 9n");
printf("please try again: ");
scanf("%s", msg);
}
sendData(p, msg);
Box my_attack_box;
my_attack_box.abs = msg[0];
my_attack_box.ord = msg[1]-'0';
updateMarkBoard(p, my_attack_box);
}
void receiveAttack(Player* p)
{
char received_attack[2];
receiveData(p, received_attack);
printf("I have received the attack: %sn", received_attack);
Box my_attack_box;
my_attack_box.abs = received_attack[0];
my_attack_box.ord = received_attack[1]-'0';
endureAttack(my_attack_box, p);
}
void play_game(Player* p)
{
while(p->state == PLAYING){
printPlayer(p); //print the game boards.
if(p->action == ATTACK){
printf("Your turn to attack.n");
attack(p); //attack the ennemy
printf("end of attack turn.n");
} else if(p->action == WAIT){
printf("wait for an attack...n");
receiveAttack(p); //receive the attack from the ennemy.
printf("end of waiting turn.n");
}
if(p->action == WAIT){
p->action = ATTACK;
}
else{
p->action = WAIT;
}
}
}
在while循环中转一圈后,程序显示"分段故障"。我的测试表明问题出在p->action
上。
请参阅下面显示问题的程序输出:输出屏幕截图。整个代码在这里可用:GitLab repo链接。这就像我的程序无法访问我的播放器的action
成员。
有人有什么想法吗?
char msg[2];
bzero(msg, strlen(msg));
好吧,在这里,您尝试计算一个未初始化字符串的长度,这是页面错误(和内核漏洞)的典型来源。strlen
不知道您的数组的大小,它只是寻找一个零字符,很可能很快就会离开您的页面。即使程序在这一点上没有崩溃,bzero
也会成功,因为它很可能会写入您无法访问的内存。
请注意,一个单元格通常至少有两个字符("C4"左右),因此scanf
将在msg
结束后写入终止零字符(同样,这可能超出了可用内存)。增加msg
的大小,使其至少可以容纳有效的输入(至少三个字符,越多越好)。您不需要在这里拨打strlen
;如果要预先清除数组,最简单的方法是正确初始化它:char msg[256] = {' '};
。
接下来,您还没有显示NewPlayer()
的代码,但您的结构包含三个指针字段,请仔细检查它们是否已正确分配和初始化。