0

我尝试运行我的 C++ 代码并尝试调试过去 1 小时。我一直在检查,但不确定我做错了什么?

如果我输入了错误的用户/密码,则代码不会有问题,但如果我正确输入了 logincheck=actionvalue,它将抛出如下所示的错误。

这是我的数据库选择语句的外观:

root@ubuntu:/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)

我的代码.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)
4

1 回答 1

0

It appears that the following line is likely the culprit.

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

Since the value returned by sqlite3_column_text can be NULL it must be checked before passing it to the constructor of std::string. Change it to something like the following.

pointer_value = (char *)sqlite3_column_text( stmt, i );
if(pointer_Value != NULL)
{
    result[i].push_back( std::string( pointer_value ) );
}
于 2012-08-13T21:31:50.557 回答