Цикл навсегда? - PullRequest
       4

Цикл навсегда?

1 голос
/ 25 марта 2011

Эй, при попытке перебрать со "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 ]

1 голос
/ 25 марта 2011

Хорошо, так что вы делаете

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);
}
1 голос
/ 25 марта 2011

Когда вы создаете новую структуру DBResult, вы устанавливаете указатель next на NULL?Если вы создадите структуру с помощью malloc, ваш тест для result никогда не закончится.

Трудно узнать больше, не зная определения DBResult и определения store_query.Что store_query возвращает?

Вы говорите, что составляете список.В store_query вы фактически не устанавливаете next из ret в tmp.Я предполагаю, что это то, что вы хотите сделать.Внимательно посмотрите на конструкцию вашего списка, потому что она не верна.

Это может помочь нарисовать картину вашего DBResult по мере его создания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...