2012-08-13 1 views
0

C++ 코드를 실행하려고 시도하고 지난 1 시간 동안 디버깅을 시도했습니다. 나는 계속 확인하고 있지만, 내가 뭘 잘못하고 있는지 확실하지 않니?sqlite select 문에서 vector 얻기를 사용할 때 C++ Logic_error

코드에 문제가 없을 것입니다. 잘못된 사용자/비밀번호를 입력했는데 올바르게 입력했는데 logincheck = actionvalue를 입력하면 아래에 표시된 것처럼 오류가 발생합니다. 여기

내 데이터베이스를 선택 문의 모습입니다 :

[email protected]:/home/baoky/version1.2/Assignment 2# sqlite3 abeserver.db 
SQLite version 3.7.9 2011-11-01 00:52:41 
Enter ".help" for instructions 
Enter SQL statements terminated with a ";" 
sqlite> select * from abe_account; 
admin|Peter John|admin|password 

if (logincheck==actionvalue) 

내 code.cpp

#include <iostream> 
#include <stdlib.h> 
#include <stdio.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <sys/un.h> 
#include <vector> 
#include <string> 
#include <fstream> 
#include <sqlite3.h> 

#define DEFAULT_PROTOCOL 0 
#ifndef AF_LOCAL 
#define AF_LOCAL AF_UNIX 
#endif 
#ifndef PF_LOCAL 
#define PF_LOCAL PF_UNIX 
#endif 

//g++ -o test test.cpp -lsqlite3 (sample compile with sqlite3) 

using namespace std; 
/* THIS IS SERVER CODE */ 
/* I WILL USE A TEMP FILE account.txt for basic login auth check */ 

int readLine (int fd, char* str) 
{ 
    int n; 
    do /* Read characters until NULL or end-of-input */ 
    { 
    // ssize_t read (int fd, void *buf, size_t count); 
    // if successful, read will: 
    // a) stores data read into 'buf', and 
    // b) returns the no. of bytes read 
    // read returns zero if it reaches end-of-input 
     n = read (fd, str, 1); /* Read one character */ 
    } 
    while (n > 0 && *str++ != 0); 
    return (n > 0); /* Return false if end-of-input */ 
} 

string readClient (int fd) 
{ 
    char str[2000]; 

    while (readLine (fd, str)) /* Read lines until end-of-input */ 
    return(string)str; /* return as string */ 
} 


std::vector<std::string> split(std::string const& str, std::string const& delimiters = "#") { 
    std::vector<std::string> tokens; 

    // Skip delimiters at beginning. 
    string::size_type lastPos = str.find_first_not_of(delimiters, 0); 
    // Find first "non-delimiter". 
    string::size_type pos = str.find_first_of(delimiters, lastPos); 

    while (string::npos != pos || string::npos != lastPos) { 
    // Found a token, add it to the vector. 
    tokens.push_back(str.substr(lastPos, pos - lastPos)); 
    // Skip delimiters. Note the "not_of" 
    lastPos = str.find_first_not_of(delimiters, pos); 
    // Find next "non-delimiter" 
    pos = str.find_first_of(delimiters, lastPos); 
    } 
    return tokens; 
} 



std::vector<std::string> split(std::string const& str, char const delimiter) { 
    return split(str,std::string(1,delimiter)); 
} 




int main() 
{ 

int serverFd; 
int clientFd; 
int serverLen; 
int clientLen; 
int counter; 

string action; 
string actionvalue; 

string receiveClient; 
string sendClient; 
string department; 

string sline; 
string logincheck; 
ifstream myfile; 


struct sockaddr* serverSockAddrPtr; 
struct sockaddr* clientSockAddrPtr; 
struct sockaddr_un serverAddress; 
struct sockaddr_un clientAddress; 


//for handle zombie 
//to ignore SIGCHLD(death of child signal).The zombies will not be seen. 
signal(SIGCHLD, SIG_IGN); 
//zombies(defunct processes ps command in Linux will show defunct entries) 

cout << "" << endl; 
cout << "Running server program 'ABEServer' ...... " << endl; 
cout << "" << endl; 


// SOCKET CREATION PART - SERVER 
serverFd = socket (AF_LOCAL, SOCK_STREAM, DEFAULT_PROTOCOL); 

/* Set domain type */ 
serverAddress.sun_family = AF_LOCAL; 

/* Set name */ 
strcpy (serverAddress.sun_path, "ABEServer"); 


/* GET SIZE OF Server Addres */ 
serverLen = sizeof serverAddress; 
/* GET SIZE OF Client Addres */ 
clientLen = sizeof clientAddress; 

/* Get Server Sock Address Pointer*/ 
serverSockAddrPtr = (struct sockaddr *) &serverAddress; 
/* Get Client Sock Address Pointer*/ 
clientSockAddrPtr = (struct sockaddr *) &clientAddress; 


/* Create file */ 
unlink("ABEServer"); 
bind (serverFd, serverSockAddrPtr , serverLen); 

/* listen for connection */ 
listen (serverFd,5); 

cout << "Server started"; 
cout << "" << endl; 
// SOCKET CREATION END - SERVER 


while (1) /* Loop forever */ 
{ 
/* Accept a client connection */ 
clientFd = accept (serverFd, clientSockAddrPtr, (socklen_t*) &clientLen); 

if (fork() == 0) /* Create child to send client */ 
{ 

    while(1) 
    { 
     sendClient = ""; 
     //read client input 
     receiveClient = readClient(clientFd); 
     vector<string> x = split(receiveClient, '#'); 

action = x[0]; 
actionvalue = x[1]; 


if(action=="auth") 
{ 

logincheck = ""; 
counter = 0; 
department = ""; 


//default sendClient value 
sendClient = "fail login#Invalid username/password."; 
    sqlite3 *db; 
    sqlite3_stmt * stmt; 
    std::vector< std::vector < std:: string > > result; 
    for(int i = 0; i < 4; i++) 
    result.push_back(std::vector<std::string>()); 

    if (sqlite3_open("abeserver.db", &db) == SQLITE_OK) 
    { 
    sqlite3_prepare(db, "SELECT * from abe_account;", -1, &stmt, NULL);//preparing the statement 
    sqlite3_step(stmt);//executing the statement 

    while(sqlite3_column_text(stmt, 0)) 
     { 
    for(int i = 0; i < 4; i++) 
    result[i].push_back(std::string((char *)sqlite3_column_text(stmt, i))); 
    sqlite3_step(stmt); 
    counter++; 
     } 
    //close connection to db and finalize sql statement 
        sqlite3_finalize(stmt); 
        sqlite3_close(db); 
     //username:password // using first record to check 
       for (int i = 0; i < counter; i ++) 
       { 
       //result[column][row] 
       logincheck = result[0][i] + ":" + result[3][i]; 
       department = result[2][i]; 
       } 

       if (logincheck==actionvalue) 
       { 
       //send back in format of login done, login message, department level 
       sendClient = "login done#Successfully Login"; 
       break; 
       } 
    result.clear(); 
} 
}//end if auth 

    write (clientFd, sendClient.c_str(), strlen (sendClient.c_str()) + 1); 
    }//end while  



}//end if fork 



     else 
     { 
     close (clientFd); /* Close the client descriptor */ 
     }//end else 


}//end while outer 


return 0; 
} 

오류 메시지 :

Username > admin 
Password > password 
terminate called after throwing an instance of 'std::logic_error' 
    what(): basic_string::_S_construct null not valid 
Segmentation fault (core dumped) 
+1

std :: string에 널 포인터를 지정하려는 것처럼 보입니다. –

+0

가능한 복제본 : [오류를 피하는 방법 : 'std :: logic_error'의 인스턴스를 throw 한 후에 호출 종료() : basic_string :: _ S_construct null not valid] (http://stackoverflow.com/questions/11705886/how -to-avoid-the-error-terminate-after-instance-of-stdlog) –

+0

디버거를 사용하여 예외를 throw하는 행을 찾아서 수정해야합니다. @CaptainObvlious가 말했듯이, 예외는 널 포인터로'std :: string'을 구성한다는 것을 의미합니다. –

답변

0

그것은 다음 줄 가능성이 나타납니다 그 범인. sqlite3_column_text에 의해 반환되는 값이 NULL이 될 수 있기 때문에

result[i].push_back(std::string((char *)sqlite3_column_text(stmt, i))); 

그것은 표준 : : 문자열의 생성자에 전달하기 전에 확인해야합니다. 다음과 같이 변경하십시오.

pointer_value = (char *)sqlite3_column_text(stmt, i); 
if(pointer_Value != NULL) 
{ 
    result[i].push_back(std::string(pointer_value)); 
} 
관련 문제