我在C中对复杂的客户端/服务器(多聊天室)程序进行简单的操作。
我有一个名为 node 的链接列表结构
struct node
{
char *user;
char *passwd;
int id;
int connected;
struct node *next;
};
另一种名为 room
的结构struct room
{
char *name;
int capacity;
int room_id;
int admin_id;
struct room *next;
struct node *users;
};
我将此声明为全局变量:
struct room *rooms = NULL;
我已经使用互斥锁和信号量保护它。
所以我只想在服务器结束时编写这个结构,然后在服务器再次启动时加载它。这样做的逻辑在于两个文件, server.c 和 * server_utils.c * ,如下所示:
的 server.c :
int main (void)
{
[...]
struct stat st;
[...]
stat ("rooms.bin", &st);
if (st.st_size > 0)
{
// Load rooms
load_rooms ();
}
else
{
[...]
}
[...]
exit (EXIT_SUCCESS);
}
*的 server_utils.c * :
[...]
void load_rooms (void)
{
int fd;
if ((fd = open ("rooms.bin", O_RDONLY)) < 0)
{
perror ("open");
exit (EXIT_FAILURE);
}
else
{
read (fd, &rooms, sizeof (rooms));
}
}
void save_rooms (void)
{
int fd;
if ((fd = open ("rooms.bin", O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0)
{
perror ("open");
exit (EXIT_FAILURE);
}
else
{
write (fd, &rooms, sizeof (rooms));
}
}
[...]
我发现的问题是当我用
从二进制文件中读取结构时read (fd, &rooms, sizeof (rooms));
然后我尝试用
打印结构void rooms_linkedlist_print (struct room *head)
{
struct room *curr = head;
char str[1024];
while (curr != NULL)
{
write (1, curr->name, strlen (curr->name));
write (1, "\n", strlen ("\n"));
bzero (str, 1024);
sprintf (str, "%d\n", curr->capacity);
write (1, str, strlen (str));
bzero (str, 1024);
sprintf (str, "%d\n", curr->room_id);
write (1, str, strlen (str));
bzero (str, 1024);
sprintf (str, "%d\n", curr->admin_id);
write (1, str, strlen (str));
curr = curr->next;
}
}
我遇到了分段错误(核心转储)。关于我做错了什么想法?
答案 0 :(得分:2)
你的房间结构里面有指针。
当您重新加载数据时,这些指针将不再一定指向已分配的内存,从而导致分段错误。
您可以通过将指针更改为使用索引更改为rooms数组来解决此问题。