Reputation: 41
I'm getting an error saying my expression must have a pointer to type class, I'm trying to dynamically allocate an array of pointers to an object vector.
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;
}
Upvotes: 0
Views: 77
Reputation: 596156
sortedRec
is a Record***
, so sortedRec[i]
is a Record**
. You can't use the ->
operator to dereference a pointer-to-pointer. You need to use the *
operator instead to dereference the Record**
pointer-to-pointer into a single Record*
pointer, like you do in your for
loop. Then, you can use the ->
operator to dereference that Record*
pointer to access the members of the Record
instance, eg:
cout << (*sortedRec[i])->name << endl;
That being said, VERY VERY RARELY in C++ do you ever need to use 3 levels of indirection, like you are (Record*** sortedRec
).
No matter how sortedRec
is passed, records
should be passed by reference so that dmaArr()
is not acting on a copy of the caller's vector<Record>
, leaving sortedRec
holding dangling pointers when the copy is destroyed when dmaArr()
exits:
void dmaArr(..., vector<Record> &records)
Then, you can and should replace one level of pointer indirection on sortedRec
by using a reference instead of a pointer:
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;
Then, you can and should replace another level of pointer indirection on sortedRec
by using std::vector
instead of new[]
. Let std::vector
manage the dynamic memory for you, especially since the caller is already using std::vector
anyway:
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...
Upvotes: 1
Reputation: 32732
In your cout
statement, sortedRec[i]
has type Record**
, which you cannot use with the pointer dereference operator. You can use (*sortedRec[i])->name
to get the name field of the record just assigned.
Incidentally, because you pass records
by value, all the pointers stored in your for loop are to this temporary object and will be danging once the function returns. You should pass records
by reference: vector<Record> &records
to avoid that.
Upvotes: 2