передача двойного указателя по ссылке

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

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

person Brett    schedule 06.03.2020    source источник


Ответы (2)


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

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

person 1201ProgramAlarm    schedule 06.03.2020

sortedRec — это Record***, поэтому sortedRec[i] — это Record**. Вы не можете использовать оператор -> для разыменования указателя на указатель. Вместо этого вам нужно использовать оператор * для разыменования указателя Record** в один указатель Record*, как вы делаете в своем цикле for. Затем вы можете использовать оператор -> для разыменования этого указателя 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 управлять динамической памятью вместо вас, тем более что вызывающая программа уже использует 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...
person Remy Lebeau    schedule 06.03.2020
comment
``` (** &sortedRec) ``` не изменяет значение в main. Я согласен использовать другой вектор, но меня заставили написать его с массивом dma указателей, указывающих на мой вектор для. - person Brett; 06.03.2020
comment
Record** &sortedRec ИЗМЕНЯЕТ указатель в main(), если вы называете его как Record** sortedRec; dmaArr(sortedRec, ...);, а не как Record** sortedRec; dmaArr(&sortedRec, ...);, я обновил свой ответ, чтобы продемонстрировать это. Это C++, а не C, вы не должны использовать указатели там, где будет достаточно ссылок. - person Remy Lebeau; 06.03.2020