передача двойного указателя по ссылке - PullRequest
0 голосов
/ 06 марта 2020

Я получаю сообщение о том, что в моем выражении должен быть указатель на класс типов, я пытаюсь динамически распределить массив указателей на объектный вектор.

void dmaArr(Record*** sortedRec, vector<Record> records) {
    //sortedRec = nullptr;
    *sortedRec = new Record *[records.size()];
    cout << *sortedRec << endl << sortedRec << endl;
    for (int i = 0; i < records.size(); i++) {
        *sortedRec[i] = &records[i];
        cout << sortedRec[i]->name << '\t' << &sortedRec[i]->name << endl;
    }

Ответы [ 2 ]

2 голосов
/ 06 марта 2020

В вашем операторе cout sortedRec[i] имеет тип Record**, который нельзя использовать с оператором разыменования указателя. Вы можете использовать (*sortedRec[i])->name, чтобы получить поле имени только что назначенной записи.

Кстати, поскольку вы передаете records по значению, все указатели, хранящиеся в вашем поле для l oop, относятся к этому временному объекту. и будет опасным, как только функция вернется. Вы должны передать records по ссылке: vector<Record> &records, чтобы избежать этого.

1 голос
/ 06 марта 2020

sortedRec - это Record***, поэтому sortedRec[i] - это Record**. Вы не можете использовать оператор -> для разыменования указателя на указатель. Вместо этого вам нужно использовать оператор *, чтобы разыменовать указатель Record** на указатель в один указатель Record*, как вы делаете это в вашем for l oop. Затем вы можете использовать оператор -> для разыменования этого указателя Record* для доступа к членам экземпляра Record, например:

cout << (*sortedRec[i])->name << endl;

При этом ОЧЕНЬ ОЧЕНЬ РЕЖНО в C ++ когда-либо нужно использовать 3 уровня косвенности, как вы (Record*** sortedRec).

Независимо от того, как передан sortedRec, records должен быть передан по ссылке, чтобы dmaArr() не действовал на копия номера vector<Record> вызывающего абонента, при этом sortedRec удерживает висячие указатели, когда копия уничтожается при выходе из dmaArr():

void dmaArr(..., vector<Record> &records)

Затем, Вы можете и заменить один уровень косвенности указателя на sortedRec, используя вместо указателя ссылку:

void dmaArr(Record** &sortedRec, vector<Record> records) {
    sortedRec = new Record *[records.size()];
    for (size_t i = 0; i < records.size(); ++i) {
        sortedRec[i] = &records[i];
        cout << sortedRec[i]->name << endl;
    }
    ...
}
vector<Record> records;
Record** sortedRecords;

// populate records as needed...

dmaArr(sortedRecords, records);

// use sortedRecords as needed...

delete [] sortedRecords;

Затем вы можете и должны замените другой уровень косвенности указателя на sortedRec, используя std::vector вместо new[]. Позвольте std::vector управлять динамической c памятью для вас, тем более что вызывающая сторона все равно уже использует std::vector:

void dmaArr(vector<Record*> &sortedRec, vector<Record> &records) {
    sortedRec.resize(records.size());
    for (size_t i = 0; i < records.size(); ++i) {
        sortedRec[i] = &records[i];
        cout << sortedRec[i]->name << endl;
    }
    ...
}
vector<Record> records;
vector<Record*> sortedRecords;

// populate records as needed...

dmaArr(sortedRecords, records);

// use sortedRecords as needed...
...