将对象添加到矢量时的分段错误

时间:2015-05-05 01:50:26

标签: c++ qt object vector

当我向向量“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(....),但我看不出原因。

1 个答案:

答案 0 :(得分:1)

showRenters()showAll()都访问尚未推送的list元素,因此无效。即使元素有效,showRenters()showAll()也会将多个指针推送到相同的局部变量,这样做无效。在每次循环迭代中,变量都会被新数据覆盖,因此最终会有多个vector元素引用相同的物理数据。更糟糕的是,当showRenters()showAll()退出时,变量超出范围并被释放,导致返回的向量充满无效指针。

如果要返回字符串的二维向量,请改用:

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...
}

否则,更改代码以返回Client*指针的1维向量,并让调用者根据需要决定如何处理客户端数据。只要在调用者使用返回的向量时未更改clientVectClient*指针将保持有效:

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...
}