存储在列表中的对象具有相同的ID或指向同一对象

时间:2013-11-05 12:08:21

标签: c pointers

我试图在可以连接套接字的服务器上制作一个简单的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 = &timestamp;
    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次添加客户端并打印列表后,我得到了这个输出:

  1. 列表中的空白位置
  2. 添加客户端...(ID94630956) 添加了管理客户端(ID = 41)。
  3. 列表中的空白位置
  4. 添加客户端...(ID94630956) 添加了管理客户端(ID = 18467)。
  5. 列表中的空白位置
  6. 添加客户端...(ID94630956) 添加了管理客户端(ID = 6334)。
  7. 列表中的空白位置
  8. 添加客户端...(ID94630956) 添加了管理客户端(ID = 26500)。
  9. 列表中的空白位置
  10. 添加客户端...(ID94630956) 添加了管理客户端(ID = 19169)。
  11. 列表中的空白位置
  12. 添加客户端...(ID94630956) 添加了管理客户端(ID = 15724)。
  13. 列表中的空白位置
  14. 添加客户端...(ID94630956) 添加了管理客户端(ID = 11478)。
  15. 列表中的空白位置
  16. 添加客户端...(ID94630956) 添加了管理客户端(ID = 29358)。
  17. 列表中的空白位置
  18. 添加客户端...(ID94630956) 添加了管理客户端(ID = 26962)。
  19. 列表中的空白位置
  20. 添加客户端...(ID94630956) 添加了管理客户端(ID = 24464)。
  21. 添加了管理客户端(ID = 0)。

    添加了管理客户端(ID = 0)。

    打印法力客户名单......

    1. ID = 3435973836的客户。
    2. ID = 3435973836的客户。
    3. ID = 3435973836的客户。
    4. ID = 3435973836的客户。
    5. ID = 3435973836的客户。
    6. ID = 3435973836的客户。
    7. ID = 3435973836的客户。
    8. ID = 3435973836的客户。
    9. ID = 3435973836的客户。
    10. ID = 3435973836的客户。
    11. 我个人认为问题与我存储或传递对象/值的方式有关,但我并不完全确定。任何有关这方面的帮助将不胜感激。

1 个答案:

答案 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;

这会分配一个新结构,并将已初始化的结构复制到该新结构。