2015-05-05 4 views
-1

Когда я добавляю объекты в вектор «clientVect», я получаю ошибку сегментации. Можете ли вы помочь мне определить проблему?Ошибка сегментации при добавлении объекта в вектор

Это класс:

#include "ClientDB.h" 

ClientDB::ClientDB(){ 
} 

ClientDB::~ClientDB(){ 
} 


void ClientDB::addClient(QString name,QString fname,int id,QString bdate,int cellnb) 
{ 
    Client c= Client(name,fname,id,bdate,cellnb); 
    this->clientVect.push_back(c); 
} 

vector <vector<QString*> > ClientDB::showRenters(){ 
    using namespace std; 
    int i; 
    int j=0; 
    QString id,cellnb,rentedcar; 
    vector <vector<QString*> > list; 
    for(i=0;i<clientVect.size();i++){ 
     if (clientVect[i].renter==true){ 
      (list[j]).push_back(&clientVect[i].name); 
      (list[j]).push_back(&clientVect[i].fname); 
      id=QString::number(clientVect[i].id); 
      (list[j]).push_back(&id); 
      (list[j]).push_back(&clientVect[i].bdate); 
      cellnb=QString::number(clientVect[i].cellnb); 
      (list[j]).push_back(&cellnb); 
      rentedcar=QString::number(clientVect[i].rentedCar); 
      (list[j]).push_back(&rentedcar); 
      j++; 
     } 

    } 
    return list; 
} 

vector <vector<QString*> > ClientDB::showAll(){ 
    using namespace std; 
    int i; 
    QString id,cellnb,rentedcar; 
    vector <vector<QString*> > list; 
    for(i=0;i<clientVect.size();i++){ 

      (list[i]).push_back(&clientVect[i].name); 
      (list[i]).push_back(&clientVect[i].fname); 
      id=QString::number(clientVect[i].id); 
      (list[i]).push_back(&id); 
      (list[i]).push_back(&clientVect[i].bdate); 
      cellnb=QString::number(clientVect[i].cellnb); 
      (list[i]).push_back(&cellnb); 
      rentedcar=QString::number(clientVect[i].rentedCar); 
      (list[i]).push_back(&rentedcar); 
    } 
    return list; 
} 

Это заголовок:

#ifndef CLIENTDB_H 
#define CLIENTDB_H 
#include "Client.h" 
#include <vector> 
#include <QString> 

using namespace std; 
class ClientDB 
{ 
public: 
    vector<Client> clientVect; 
    void addClient(QString,QString,int,QString,int); 
    vector <vector<QString*> >showRenters(); 
    vector <vector<QString*> >showAll(); 
    ClientDB(); 
    ~ClientDB(); 
}; 

#endif // CLIENTDB_H 

Проблема, конечно, в ClientDB::addClient, в частности, в clientVect.push_back(....), но я не могу понять причину.

+0

Попробуйте подключить отладчик ... вы узнаете тонну! :) – Barett

ответ

1

showRenters() и showAll() оба доступа к list элементам, которые еще не были нажаты и, следовательно, являются недействительными. Даже если элементы действительны, showRenters() и showAll() также нажимают несколько указателей на одни и те же локальные переменные, которые не будут работать. На каждой итерации цикла переменные переписываются новыми данными, поэтому вы получаете несколько элементов vector, ссылающихся на одни и те же физические данные. И что еще хуже, когда выходят showRenters() и , переменные выходят из области действия и освобождаются, оставляя возвращенные векторы полными недействительных указателей.

Если вы хотите вернуть 2-мерный вектор строк, используйте вместо этого:

vector <vector<QString> > ClientDB::showRenters(){ 
    using namespace std; 
    vector <vector<QString> > list; 
    // optional: list.reserve(clientVect.size()); 
    for(int i=0;i<clientVect.size();i++){ 
     if (clientVect[i].renter){ 
      vector<QString> values; 
      // optional: values.reserve(6); 
      values.push_back(clientVect[i].name); 
      values.push_back(clientVect[i].fname); 
      values.push_back(QString::number(clientVect[i].id)); 
      values.push_back(clientVect[i].bdate); 
      values.push_back(QString::number(clientVect[i].cellnb)); 
      values.push_back(QString::number(clientVect[i].rentedCar)); 
      list.push_back(values); 
     } 
    } 
    return list; 
} 

vector <vector<QString> > ClientDB::showAll(){ 
    using namespace std; 
    vector <vector<QString> > list; 
    // optional: list.reserve(clientVect.size()); 
    for(int i=0;i<clientVect.size();i++){ 
      vector<QString> values; 
      // optional: values.reserve(6); 
      values.push_back(clientVect[i].name); 
      values.push_back(clientVect[i].fname); 
      values.push_back(QString::number(clientVect[i].id)); 
      values.push_back(clientVect[i].bdate); 
      values.push_back(QString::number(clientVect[i].cellnb)); 
      values.push_back(QString::number(clientVect[i].rentedCar)); 
      list.push_back(values); 
    } 
    return list; 
} 

vector <vector<QString> > list = db.showRenters(); // or showAll() 
for (int i=0; i<list.size();i++) { 
    vector<QString> &values = list[i]; 
    // use values as needed... 
} 

В противном случае, изменить код, чтобы вернуть 1-мерный вектор Client* указателей вместо этого, и позвольте собеседнику решить, что делать с данными клиента по мере необходимости. Пока clientVect не изменяется, а вызывающий абонент использует возвращаемые векторов, то Client* указатели будут оставаться в силе:

vector <Client*> ClientDB::showRenters(){ 
    using namespace std; 
    vector <Client*> list; 
    // optional: list.reserve(clientVect.size()); 
    for(int i=0;i<clientVect.size();i++){ 
     if (clientVect[i].renter){ 
      list.push_back(&clientVect[i]); 
     } 
    } 
    return list; 
} 

vector <Client*> ClientDB::showAll(){ 
    using namespace std; 
    vector <Client*> list; 
    // optional: list.reserve(clientVect.size()); 
    for(int i=0;i<clientVect.size();i++){ 
     list.push_back(&clientVect[i]); 
    } 
    return list; 
} 

vector <Client*> list = db.showRenters(); // or showAll() 
for (int i=0; i<list.size();i++) { 
    Client *client = list[i]; 
    // use client as needed... 
} 
+0

Спасибо, я не думал прямо: p. Может ли это быть причиной ошибки сегментации? потому что это происходит только при вызове ClientDB :: addClient. –

+0

Проблема не в 'addClient()'. Проблема заключается в том, что 'showRenters()' и 'showAll()' возвращают неправильно заполненные векторы, заставляя вызывающего абонента обращаться к недопустимым данным. –