嘿,在尝试使用“next”迭代作为我的结构中的指针时,它会无缘无故地循环,即使我尝试制作一个指向结构的假指针(而不是调用函数来设置它)
我的代码:
void
command_login(conn,msg)
void *conn;
const char *msg;
{
const char *u,*p;
char *home;
ConnectionQueue* q;
DBResult *result;
DBResult *tmp;
bool got_pass,got_user,admin;
if (!conn)
return;
/* initalize */
q = (ConnectionQueue *)conn;
got_pass = false; got_user = false; admin = false;
result = NULL;
tmp = NULL;
if (msg == NULL || *msg == '\0'){
send_socket(q->conn,"LOGIN: Invalid user and password\n");
return;
}
(void)strtok((char *)msg," ");
u = strtok((char *)NULL, " ");
p = strtok((char *)NULL, " ");
if (!u || !p){
send_socket(q->conn,"LOGIN: Invalid user or password\n");
return;
}
printf("command_login(): u = %s, p = %s\n",u,p);
tmp = store_query("SELECT * FROM `users`");
if (!tmp){
/* should never happen */
send_socket(q->conn,"LOGIN: Failed to fetch results\n");
return;
}
printf("command_login(): Checking user and password...\n");
result = tmp;
while (result != NULL){
if (!got_user){
if (strcmp(result->field_name,"user") == 0 && strcmp(result->field_value,u) == 0)
got_user = true;
}else if (!got_pass){
if (strcmp(result->field_name,"pass") == 0){
if (strcmp(result->field_value,transform_password(p)) == 0)
got_pass = true;
}
}else if (!admin){
if (strcmp(result->field_name,"admin") == 0){
admin = boolean_string(result->field_value);
}
}else{
break;
}
result = result->next;
}
free_result(result);
printf("command_login(): Checking got user and got password\n");
if (!got_user || !got_pass){
send_socket(q->conn,"LOGIN: Invalid user or password\n");
return;
}
printf("command_login(): Login successfully\n");
send_socket(q->conn,"LOGIN: Success\n");
q->conn->state &= ~S_NEED_LOGIN;
q->admin = admin;
#ifndef _WIN32
home = getenv("HOME");
#else
home = getenv("HOMEPATH");
#endif
if (!home)
return;
if (!chdir(home)){
send_socket(q->conn,"LOGIN: Failed to change to user home directory %s: %s\n",home,strerror(errno));
close_connection(q->conn);
return;
}
send_socket(q->conn,"CWD: %s\n",home);
}
它永远在这里循环:
while (result != NULL){
if (!got_user){
if (strcmp(result->field_name,"user") == 0 && strcmp(result->field_value,u) == 0)
got_user = true;
}else if (!got_pass){
if (strcmp(result->field_name,"pass") == 0){
if (strcmp(result->field_value,transform_password(p)) == 0)
got_pass = true;
}
}else if (!admin){
if (strcmp(result->field_name,"admin") == 0){
admin = boolean_string(result->field_value);
}
}else{
break;
}
result = result->next;
}
任何想法?感谢
答案 0 :(得分:1)
当您创建新的DBResult
结构时,是否将next
指针设置为NULL
?如果您使用malloc
创建结构,则result
的测试将永远不会结束。
如果不了解DBResult
的定义和store_query
的定义,就很难了解更多内容。 store_query
返回什么?
你说你正在制作一份清单。在store_query
中,您实际上并未将next
的{{1}}设置为ret
。我认为这就是你想要做的。仔细查看列表构造,因为它不正确。
在构建tmp
时,绘制一幅图片可能会有所帮助。
答案 1 :(得分:1)
好的,你正在做的是
ret->next = tmp;
ret = tmp;
ret->next = tmp; // = ret
所以你用一个元素制作一个循环链表。您需要做的是每次添加一个元素时分配一个新元素。然后记得最后释放它们。
修改的
模式应如下所示
DBResult* head = NULL;
DBResult* row = NULL;
while(have_rows()) {
row = malloc(sizeof(DBResult));
// load row into row
row->next = head;
head = row;
}
return head;
// later when you're all done
while(head) {
DBResult* element = head;
head = head->next;
free(element);
}