永远循环?

时间:2011-03-25 01:13:30

标签: c

嘿,在尝试使用“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;
  }

任何想法?感谢

2 个答案:

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