我正在使用这个链接列表库,但是在列出已保存的客户端时遇到问题,我只获得了最后一个插入客户端。 注意到list_iterator_next()函数返回一个void指针, 我的代码中有什么问题?
#include <stdio.h>
#include <string.h>
#include "simclist.h" /* use the SimCList library */
int main() {
// initialize clients
list_t clients;
// structure to append
typedef struct client{
char ip[45];
int port;
} client;
client client1;
int i;
char ip[45];
int port;
// initialize the list
list_init(&clients);
for( i = 1 ; i <= 3; i++ ){
printf("Insert your ip: ");
scanf("%s", &ip);
strcpy( client1.ip , ip );
printf("Insert your port:");
scanf("%d", &port);
client1.port = port;
list_append(&clients, &client1);
}
// size of list
printf("The list now holds %u elements.\n", list_size(&clients));
// starting iterator session
list_iterator_start(&clients);
// check if there is more values
while (list_iterator_hasnext(&clients)) {
// get the next value
client show_client = *(client *)list_iterator_next(&clients);
printf("%s:%d\n", show_client.ip, show_client.port);
}
list_iterator_stop(&clients);
list_destroy(&clients);
return 0;
}
答案 0 :(得分:0)
这不是一个完整的答案,但您可以使用此类数组查看@JonathanLeffler注释。然后,您将了解列表库是否正在 结构指针,或整个数据结构内容。
请注意i
循环中的更改,在&
中的字符串标识符之前省略scanf()
,并在结构字段上直接使用scanf()
。最后 - 注意字符串长度!
client client1[3];
for( i=0 ; i<3; i++ ){
printf("Insert your ip: ");
scanf("%44s", client1[i].ip);
printf("Insert your port:");
scanf("%d", &client1[i].port);
if (list_append(&clients, &client1[i]) != 1) {
printf ("List append failed\n");
exit (1);
}
}
修改强>
回到这一点,答案显而易见。由于int list_append(list_t *restrict l, const void *data)
唯一知道的struct client
是指向它的void*
指针,因此它不可能知道要复制的数据的大小,因此可能知道它创建的列表中的外部数据,仅包含它给出的指针。所以@JonathanLeffler是正确的:通过为每次插入传递相同的struct
指针,列表的所有元素都具有相同的指针,因此只有最新的数据。
答案 1 :(得分:0)
正如Jonathan Leffler已经提出的那样,您需要为每个客户端动态分配内存。 SimCList不会为你做那件事;它不能也不会对你的记忆管理负责。
替换此行:
list_append(&clients, &client1);
由:
list_append(&clients, duplicate_client(&client1));
duplicate_client
的天真实现是:
client *duplicate_client(client *c)
{
return memcpy(malloc(sizeof(client)), c, sizeof(client));
}
但强烈建议使用一些异常处理(以防止malloc
返回NULL时出现段错误。)
免责声明:我没有对此进行测试。
偏离主题:请花一些时间来防止内存超支; scanf
和strcpy
不安全。