我试图在可以连接套接字的服务器上制作一个简单的CRUD管理器客户端(用C语言,我不熟悉但我别无选择)。通过使用会话ID,服务器将同时保持10个同时连接。问题是,当我在添加10个客户端后打印列表时,它会显示一个包含相同对象10倍的列表(或者10个具有相同ID的对象,这是我有点困惑的地方)。
这是我如何声明管理器客户端的结构并声明列表(可以容纳其中10个):
typedef struct Mana_client {
int client_id;
int timestamp_connection;
char privilege_level;
}Mana_client;
Mana_client *mana_client_list[10];
srand(time(NULL)); // is called once when initializing the thread.
这就是我写这个'将客户添加到列表中的方法。 :
int add_mana_client()
{
int i=0;
int client_id = 0;
int timestamp = 0;
Mana_client client = { client_id, timestamp, 1};
client_id = rand()%100000;
timestamp = time(NULL);
client.client_id = &client_id;
client.timestamp_connection = ×tamp;
for(i=0; i <10; i++)
{
if(mana_client_list[i] == NULL){
printf("%u. Empty spot in list\n", i);
if(!contains_mana_client_id(client_id)){
printf("%u. Adding client... (with ID%u)\n", i, client.client_id);
mana_client_list[i] = &client;
return client_id;
}
}
}
return 0;
}
这是我检查具有相同ID的客户端是否已在列表中的方式:
int contains_mana_client_id(int id)
{
int i=0;
for(i=0; i <10; i++)
{
if(mana_client_list[i] != NULL){
if(id == mana_client_list[i]->client_id){
printf("%u. Client with ID=%u found.\n", i, id);
return 1;
}
}
}
return 0;
}
然后,检查列表及其客户:
void print_mana_client_list()
{
int i=0;
printf("Printing list of mana clients...\n\n");
for(i=0; i <10; i++)
{
if(mana_client_list[i] != NULL){
printf("%u. Client with ID=%u.\n", i, mana_client_list[i]->client_id);
}else{
printf("%u. Empty.\n", i);
}
}
}
运行方法连续12次添加客户端并打印列表后,我得到了这个输出:
添加了管理客户端(ID = 0)。
添加了管理客户端(ID = 0)。
打印法力客户名单......
我个人认为问题与我存储或传递对象/值的方式有关,但我并不完全确定。任何有关这方面的帮助将不胜感激。
答案 0 :(得分:1)
这是因为他们 相同。当你这样做
mana_client_list[i] = &client;
始终使用指向局部变量的指针。相反,您应该为循环中的每个迭代创建一个新的结构实例。为此,您需要使用malloc
为结构分配内存。完成后不要忘记free
那段记忆。
这也将解决你遇到的另一个问题,那就是保存指向局部变量的指针,一旦函数add_mana_client
返回,它将超出范围。在函数返回后使用该指针是未定义行为的情况,你很幸运它可以工作。
一种简单的方法,无需对当前代码进行多次修改,可能类似于以下代码来替换当前的mana_client_list[i] = &client;
行:
mana_client_list[i] = malloc(sizeof(Mana_client));
*mana_client_list[i] = client;
这会分配一个新结构,并将已初始化的结构复制到该新结构。