2011-03-25 14 views
1

ちょっと、私の構造体のポインタとして "次"を反復しようとしている間に、構造体への偽のポインタを作成しようとしても、それは何の理由もなく永遠にループします。永遠にルーピング?

私のコード:

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

のようになりますか? – Alex

+0

@Alex:メインのポストにも追加しました:p –

答えて

1

新しいDBResult構造体を作成するときは、nextポインタをNULLに設定しますか? mallocで構造を作成すると、resultのテストは終了しません。

DBResultの定義とstore_queryという定義を知らなくても、もっと知ることは本当に難しいです。 store_queryは何を返しますか?

リストを作成しているとします。 store_queryでは、nextrettmpに設定されていません。私はそれがあなたがしたいことだと思います。それが正しくないのであなたのリスト構築を注意深く見てください。

DBResultの画像を描画するのに役立つかもしれません。

+0

"result-> field_value"と "result-> field_name"を出力すると、正しく出力されますが、永遠に同じ値を出力します...とにかくDBResult構造体&store_queryからメインポスト –

+0

store_queryを見ると、リンクされたリストがどのようにつながっているかわかりません。あなたはリンクされたリストを作っていますか?あなたは、戻り値のデータ構造がどのようなものになっているのか説明できますか? – Starkey

+0

はい、sqliteからフェッチされた結果のリストを作っています:P –

1

わかりましたので、何をやっていると、あなたは一つの要素を持つ円形のリンクリストを作っている

ret->next = tmp; 
ret = tmp; 
ret->next = tmp; // = ret 

です。必要なのは、追加するたびに新しい要素を割り当てることです。最後にすべてを解放することを忘れないでください。

編集

はパターンが `addto_dbresult`何をするのか、この

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); 
} 
+0

"store_query"で "tmp"配列を作ろうとしましたが、それはうまく動作しません。 –

+0

これは動作しません。 'DBResult tmp [1]'のような配列はスタックに割り当てられ、 'store_query'が返ってきたら破棄されます。つまり、リストに追加する要素ごとに 'malloc'を1回呼び出す必要があります。 – Alex

+0

新しい要素を追加するたびに割り当てることを意味するコードを追加しました。 – Alex

関連する問題