动态内存分配——所有对象都是一样的

Dynamic Memory Allocation - All objects are the same

本文关键字:一样 分配 内存 对象 动态      更新时间:2023-10-16

我正在编写一个c++程序,它读取乘客列表并创建存储在动态分配指针中的Passenger对象。然而,我注意到,当我运行程序时,添加一个新乘客会导致之前设置的所有乘客也被分配给新乘客。

下面可能有问题的代码段:

int x = 400;
passengerslot = 0;
Passenger * list = new Passenger[x];
ifstream myfile("Airline.CSV");
if (myfile.is_open())
{
    while (getline(myfile, line))
    {
        std::istringstream ss(line);
        std::string token;
        int dataslot = 0;
        while (std::getline(ss, token, ',')) {
            switch (dataslot){
            case 0:
                *last = token;
                break;
            case 1:
                *first = token;
                break;
            case 2:
                *rownum = atoi(token.c_str());
                break;
            case 3:
                *seat = token.at(0);
                break;
            case 4:
                *flightnum = atoi(token.c_str());
                list[passengerslot] = *new Passenger(last, first, rownum, flightnum, seat);
                cout << list[passengerslot].getPassenger() << endl; //prints as the passengers are assigned
                if (passengerslot != 0){
                    cout << list[passengerslot - 1].getPassenger() << endl;
                }

我的乘客构造函数:

Passenger::Passenger(string *fname, string *lname, int *rownum, int *flightnum, char *seatchar):firstname(fname), lastname(lname), rownumber(rownum), flightnumber(flightnum), seat(seatchar){
*firstname = *fname;
*lastname = *lname;
*rownumber = *rownum;
*flightnumber = *flightnum;
*seat = *seatchar;
}

几乎所有内容的不寻常的解引用让我担心您可能会反复重用相同的指针,每次都在相同的内存位置上写入,然后将这些内存位置分配给Passenger内部的指针。

例如构造函数:

Passenger::Passenger(string *fname, string *lname, int *rownum, int *flightnum, char *seatchar):firstname(fname), lastname(lname), rownumber(rownum), flightnumber(flightnum), seat(seatchar)
{
    *firstname = *fname;
    *lastname = *lname;
    *rownumber = *rownum;
    *flightnumber = *flightnum;
    *seat = *seatchar;
}

firstname(fname)表示必须是指向string的指针,如果程序编译,firstname将被分配fname所指向的地址。对于其他成员和相关形参,遵循相同的模式。

*firstname = *fname;无效。它将字符串fname复制到字符串firstname之上,因为前一点的赋值是完全相同的位置。

这意味着所有的Passenger::firstname s都指向fname,所有的Passenger::lastname s都指向lname,等等…最终的结果是,所有的乘客看起来与最近的乘客完全相同。

解决方案:停止使用指针。你可能不需要任何指针。

累积变量应为:

std::string first;
std::string last; 
int rownum;
int flightnum;
char seat;

乘客应:

class Passenger
{
public:
    Passenger(const std::string & fname, 
              const std::string & lname, 
              int rownum, 
              int flightnum,
              char seatchar);
    // other unspecified public methods
private:
    std::string firstname; 
    std::string lastname;
    int rownumber;
    int flightnumber;
    char seat;
    // other unspecified private data and methods
}

和构造函数

Passenger::Passenger(const std::string & fname, 
                     const std::string & lname, 
                     int rownum, 
                     int flightnum,
                     char seatchar):
    firstname(fname), lastname(lname), rownumber(rownum), 
    flightnumber(flightnum), seat(seatchar)
{
}

存储定义
Passenger * list = new Passenger[x];

应该更接近

std::vector<Passenger> list;

std::vector是一个动态调整大小的数组,内置了大多数用例所需的所有内存管理。

而不是用

加载列表
list[passengerslot] = *new Passenger(last, first, rownum, flightnum, seat);
使用

list.emplace_back(first, last, rownum, flightnum, seat);