As part of a small project I'm doing to learn Qt, I'm trying to return an array of objects through a function. I then want to retrieve this array properly 开发者_StackOverflow中文版and use it's content. Right now, I only print a couple values of a single attribute to try and make it work.
The problem I have is that when I try to print its content, only the first item in the array holds the proper value (the rest seem to be random bit patterns).
Here is the return function:
QLine* LinesData::getList(){
QLine *lineList2[50];
for(int i = 0; i < 50; i++){
lineList2[i] = new QLine(10, 10 * i, 100, 100);
}
return *lineList2;}
And here is the function that attempts to use it:
void runtimeWindow::drawAllLines(){
QLine* lines = linesData.getList();
for(int i = 0; i < 5; i++){
qDebug() << lines[i].x1();
}
}
Use std::vector
and std:shared_ptr
as in:
std::vector<std::shared_ptr<QLine> > LinesData::getList(){
std::vector<std::shared_ptr<QLine> > lineList2;
for(int i = 0; i < 50; ++i){
lineList2.push_back(new QLine(10, 10*i, 100, 100));
}
return lineList2;}
and
void runtimeWindow::drawAllLines(){
std::vector<std::shared_ptr<QLine> > lines = linesData.getList();
for(auto i = lines.begin(); i != lines.end(); ++i){
qDebug() << (*i)->x1();
}
}
If you don't have std::shared_ptr
in your compiler, use the boost version.
Use of the std::vector
container avoids problems associated with C style (e.g. buffer overflow) and std::shared_ptr
performs a kind of garbage collection when you're done with the content of the vector to help prevent memory leaks.
You can also do this without pointers at all by doing the following:
std::vector<QLine> LinesData::getList(){
std::vector<QLine> lineList2(50);
for(int i = 0; i < 50; ++i){
lineList2[i].setLine(10, 10*i, 100, 100);
}
return lineList2;}
and then draw them using
void runtimeWindow::drawAllLines(){
std::vector<QLine> lines = linesData.getList();
for(auto i = lines.begin(); i != lines.end(); ++i){
qDebug() << i->x1();
}
}
Since you haven't allocated your data contiguously, you won't be able to use pointer arithmetic (which includes the array subscript operator) to find the other elements.
You also are forgetting to free the data. This isn't Java, memory won't deallocate itself.
It would be best to just use std::vector<QLine>
for this. Qt also provides some containers that could work.
QLine *lineList2[50];
lineList2
is an array of pointers. They are contiguous but the memory locations they are pointing at might not be. So,
return *lineList2;
You are returning the reference to first object in the sequence. But based on it's address you cannot access the other objects using []
operator. What actually you need to do is -
QLine** LinesData::getList(){
// .....
return lineList2;
}
void runtimeWindow::drawAllLines(){
QLine** lines = linesData.getList();
for(int i = 0; i < 5; i++){
qDebug() << *(lines[i]).x1(); // or lines[i]->x1();
}
}
Or simply use std::vector
which keeps away from all these pain as @Ben suggested.
You are returning the dereferenced lineList2, which is the first QLine* pointer, which you can access with lines[0]. But then lines[1] and so on is not operating on the array but the first QLine* pointer.
1st: Use containers, like std::vector
2nd: returning a heap object and transferring ownership at the same time is prone to memory leaks when a calling function does not destroy the object after use. You can modify getlist() so that it expects and populates a container instead of creating it:
void LinesData::getQlines(std::vector<QLine>& lineList2)
{
for(int i = 0; i < 50; i++)
lineList2.push_back(QLine(10, 10*i, 100, 100));
}
3rd: when you are transferring ownership of heap objects use smart pointers like shared_ptr
Use
std::vector<QLine>
or
new QLine[50]
then return that pointer. The caller is responsible for freeing this pointer.
精彩评论