2016-11-04 7 views
0

libmysql++ APIを使用してデータベースを照会しようとしていますが、これまでにというクエリを正常に実行することができました。 (その理由は、の後ろにいくつかのについては後述する)C++でmysql接続を閉じる際にセグメンテーションエラーが発生しました。解決する方法?

だから、すべてが正常に動作しますが、あなたは以下を参照することができ次第、私は接続を閉じてプログラムを終了する試みとして、 Segmentation fault (core dumped)は、表示され

shell> g++ -o test testCDB.cpp -L/usr/include/mysql -lmysqlclient -I/usr/include/mysql 

testCDB.cpp: In function ‘int main(int, char**)’: 
testCDB.cpp:122:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] 
    StudentManager manager1("localhost", "root", "ikilledkennedy.", "testDB"); 
                     ^
testCDB.cpp:122:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] 
testCDB.cpp:122:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] 
testCDB.cpp:122:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] 

shell> ./test 
Successfully connected to the database. 

Enter your query: SHOW DATABASES; 

[information_schema] 
[mysql] 
[performance_schema] 
[sys] 
[testDB] 

Do you wish to continue?(Y:1/N:0) : 1 

Enter your query: SHOW TABLES; 

[Student] 

Do you wish to continue?(Y:1/N:0) : 0 
Segmentation fault (core dumped) 

shell> 

この問題の原因は何ですか?これを解決するにはどのような対策が必要ですか? 一部クエリに部分来る

- Iは、これらのクエリは、結果セットのときIを産生しないためであると感じているすぎるSegmentation faultと出口データベース(等INSERT)に供給される特定のクエリが存在しますdisplayTable()に行を取得しようとしたか、おそらくperformQuery(char *)に結果セットを解放してください。NULLの値が検出されました。私はこれを考えているのでしょうか、あるいは他の根本的な原因がありますか?次のように

コードは次のとおりです。

#include <iostream> 
#include <string> 
#include <mysql.h> 
#include <limits> 

using namespace std; 

class StudentManager 
{ 

    private: 

     char *host; 
     char *user; 
     char *password; 
     char *database; 

     MYSQL *connection; 
     MYSQL_RES *result; 

     void init() 
     { 
      connection = mysql_init(NULL); 

      if(!mysql_real_connect(connection, host, user, password, database, 0, NULL, 0)) 
      { 
       cout << "Cannot connect to the database.\n" 
        << "Please make sure you have entered the details correctly and try again." 
        << endl; 
      } 

      else 
      { 
       cout << "Successfully connected to the database.\n" 
        << endl; 
      }  
     } 

     void displayTable() 
     { 
      MYSQL_ROW row; 

      unsigned int num_fields; 
      unsigned int i; 

      num_fields = mysql_num_fields(result); 

      cout << endl; 

      while((row = mysql_fetch_row(result))) 
      { 
       for(i = 0; i < num_fields; i++) 
       { 
        cout << "[" << (row[i] ? row[i] : "NULL") << "]"; 
       } 

       cout << endl; 
      } 

      cout << endl; 
     } 


    public: 

     StudentManager(char *host, char *user, char *password, char *database) 
     { 
      this->host  = host; 
      this->user  = user; 
      this->password = password; 
      this->database = database; 

      init(); 
     } 

     void performQuery(char *query) 
     { 
      if(mysql_query(connection, query)) 
      { 
       cout << "Query error: " 
        << mysql_error(connection) 
        << endl; 

       return; 
      } 

      result = mysql_use_result(connection); 

      displayTable(); 

      mysql_free_result(result); 
     } 


     void disconnect() 
     { 
      cout << "Closing connection..."; 

      mysql_close(connection); 

      cout << "Connection successfully closed."; 
     } 
}; 


int main(int argc, char *argv[]) 
{ 

    StudentManager manager1("localhost", "foo", "bar", "testDB"); 

    int choice = 1; 

    char *query; 

    while(1) 
    { 
     cout << "Enter your query: "; 
     cin.getline(query, 256); 

     manager1.performQuery(query); 

     cout << "Do you wish to continue?(Y:1/N:0) : "; 
     cin >> choice; 

     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 

     if(choice < 1) 
     { 
      manager1.disconnect(); 

      break; 
     } 
    } 

    return 0; 
} 
+0

valgrindをインストールし、valgrindでプログラムを実行してください。それはあなたがメモリエラーの原因を見つけるのに役立ちます。 –

+0

あなた自身の好意を持ち、すべての 'char *'を 'std :: string'に置き換えてください。問題は「魔法のように」消え、警告も消えてしまう可能性があります。そして、JavaスタイルのコンストラクタをC++で記述しないでください。初期化リストを使用します。 –

+0

@ChristianHackl ..私はJavaを使っていましたが、C++の初心者です。私はそれを学び始めたのは最近のことです。したがって、L1干渉と呼ぶことができます。 –

答えて

0

あなたが初期化されていないここにポインタを使用します。

char *query; 

while(1) 
{ 
    cout << "Enter your query: "; 
    cin.getline(query, 256); 

query変数が初期化されていない、といくつかのランダムなメモリ位置にポイントを。おそらくスタックセグメントのどこかにあります。 getlineを使用してその場所に書き込むと、スタックが破損します。これはセグメンテーション・フォルトにつながります。

問題のコードは、パフォーマンス重要であるとは思えないので、私はこのようなコードを書き換えることをお勧めしたい:

std::string line; 
while (cin.good()) 
{ 
    cout << "Enter your query: "; 
    std::getline(cin, line); 

PSが私の意見では、コードと他のいくつかの問題がありますが、以来、質問はセグメンテーションの失敗に関するものです。

+0

あなたの答えをありがとう。それは魅力のように機能します!あなたが話している他の問題を強調すると、本当にうれしく思います。 –

0

ここでは、早期に破損したメモリのようになります。

char *query; // <-- uninitialized buffer 

while(1) 
{ 
    cout << "Enter your query: "; 
    cin.getline(query, 256); 

getlineはストリームバッファに格納するからデータを読み出します。適切な長さのバッファは、あなたが割り当てなければなりません。それを修正するには、使用します。

char query[256]; 

をこれらのクエリが結果を生成しないので、私はあると感じ(INSERTなど)のデータベースに送らすぎセグメンテーションフォールトと出口が

を設定し、特定のクエリがあります

INSERTクエリは結果セットを生成しませんので、ドキュメントに従ってmysql_fetch_row(result)NULLを返します。これは正しい動作であり、理由はSegmentation faultではありません。

+0

それはそれを修正しました!もしあなたが少し正確であれば、本当に感謝しています。そして、あなたはその質問の第二部分についていくつかの光を当てることができましたか?とにかくありがとうございました。 :) –

+0

@RavishAhmadKhan 'INSERT'クエリは結果セットを生成しないので、ドキュメント[' mysql_fetch_row(result) '](http://dev.mysql.com/doc/refman/5.7/en/mysql- fetch-row.html)は 'NULL'を返します。 – Nikita

関連する問題