QList memory deallocation - qt

I'm trying to free memory after using QList, but it doesn't seem to work properly.
Here's my code:
QList<double> * myList;
myList = new QList<double>;
double myNumber;
cout << "CP1" << endl;
getchar(); // checkpoint 1
for (int i=0; i<1000000; i++)
{
myNumber = i;
myList->append(myNumber);
cout << myList->size() << endl;
}
cout << "CP2!" << endl;
getchar(); // checkpoint 2
for (int i=999999; i>0; i--)
{
myList->removeLast();
cout << myList->size() << endl;
}
cout << "CP3!" << endl;
getchar(); // checkpoint 3
delete myList;
cout << "CP4!" << endl;
getchar(); // checkpoint 4
Memory usage:
CP1: 460k
CP2:19996k
CP3:19996k
CP4:16088k
So it looks like despite removing of elements and deleting myList still large part of memory is being used. I believe there is a way to handle it but I can't find it.
Thanks in advance for any help.
Pawel

Memory manager is not required to release the memory your program has allocated. There are no problems in your deallocation.

QList is an array based list. The array expands automatically, but does not shrink automatically. Removing elements from the list does not affect the size of the array.
To trim the array down to the actual size, create a new QList and add the contents to it. Then delete the original list.
Unfortunately looks like there is no convenience method to do this, like the List.TrimExcess() in .NET.

Related

QSharedMemory not the same size

QSharedMemory is changing sizes on me.
create:
...
int size = buffer->size();
qDebug() << "buffer->size()" << size << "points" << points->size() << "share name" << sharedMemoryName;
if (!m_sharedMemory->create(size)) {
qCritical() << tr("Unable to create shared memory segment.");
return;
}
m_sharedMemory->lock();
char *to = (char*)m_sharedMemory->data();
memcpy(to, buffer->data(), qMin(m_sharedMemory->size(), size));
m_sharedMemory->unlock();
read:
QSharedMemory sharedMemory(sharedMemoryName);
if (!sharedMemory.attach(QSharedMemory::AccessMode::ReadOnly)) {
qCritical() << "Unable to attach to shared memory segment.";
return nullptr;
}
qDebug() << sharedMemoryName << sharedMemory.size();
Not the same size.
when create the size is 658824
when read the size is 659456
ok - sounds crazy now, but I run the read multiple times and all the sudden the size was correct. Then I restarted everything (same size on create) and the error came back.
edit:
I just realized that the size of the QSharedMemory is not necessarily then same as the QBuffer
memcpy(to, buffer->data(), qMin(m_sharedMemory->size(), size));
why is that and how can I know "on the other side" the correct size (without making an ugly workaround)
edit 2:
I may found it. looks like QSharedMemory reserves the memory in 4096 blocks.
solution for me is to check the QByteArray for empty
if(in.at(i) == QChar(0))
break;

How to get camera intrinsics and extrinsics in openni2?

I have a primesense carmine 1.08 and carmine 1.09. I need the intrinsic parameters for the RGB and the IR camera and the extrinsics between the two. I use pcl with openni2 support. So I need to know the sensor parameters used by openni2/pcl.
Is there a way in openni2 to find the intrinsics and the extrinsics using openni2/pcl? Libfreenect2 has option to get IR and color camera intrinsics, but are these parameters same as that in openni? Are all these parameters extracated from sensor during runtime?
I tried to get it via pcl, but i get nan for the focal length and the principal points
int main (int argc, char** argv)
{
std::string device_id ("");
pcl::io::OpenNI2Grabber::Mode depth_mode =
pcl::io::OpenNI2Grabber::OpenNI_Default_Mode;
pcl::io::OpenNI2Grabber::Mode image_mode =
pcl::io::OpenNI2Grabber::OpenNI_Default_Mode;
pcl::io::OpenNI2Grabber grabber (device_id, depth_mode, image_mode);
grabber.start();
double fx,fy,px,py;
grabber.getDepthCameraIntrinsics(fx,fy,px,py);
cout << "fx=" << fx << endl;
cout << "fy=" << fy << endl;
cout << "px=" << px << endl;
cout << "py=" << px << endl;
return (0);
}
A similar question has been asked here https://stackoverflow.com/questions/41110791/openni-intrinsic-and-extrinsic-calibration. However it hasnt recieved any answers.

Assign pair of raw pointers returned by a function to unique_ptr

I've looked around a little bit but couldn't find an answer to this.
I have a function returning a pair of pointers to objects, the situation can be simplified to:
#include <iostream>
#include <utility>
#include <memory>
std::pair<int *, int *> shallow_copy()
{
int *i = new int;
int *j = new int;
*i = 5;
*j = 7;
return std::make_pair(i, j);
}
int main(int argc, char *argv[])
{
std::pair<int *, int *> my_pair = shallow_copy();
std::cout << "a = " << my_pair.first << " b = " << *my_pair.second << std::endl;
// This is just creating a newpointer:
std::unique_ptr<int> up(my_pair.first);
std::cout << "a = " << &up << std::endl;
delete my_pair.first;
delete my_pair.second;
return 0;
}
I cannot change the return value of the function. From std::cout << "a = " << &up << std::endl; I can see that the address of the smart pointer is different from the address of the raw pointer.
Is there a way to capture tha std::pair returned by the function in a std::unique_ptr and prevent memory leaks without calling delete explicitly?
NB: The question have been edited to better state the problem and make me look smarter!
You're doing it the right way, but testing it the wrong one. You're comparing the address in first with the address of up. If you print up.get() instead (the address stored in up), you'll find they're equal.
In addition, your code has a double-delete problem. You do delete my_pair.first;, which deallocates the memory block pointed to by my_pair.first and also by up. Then, the destructor of up will deallocate it again when up goes out of scope, resulting in a double delete.
You also asked how to capture both pointers in smart pointers. Since the constructor of std::unique_ptr taking a raw pointer is explicit, you cannot directly do this with a simple std::pair<std::unique_ptr<int>, std::unique_ptr<int>>. You can use a helper function, though:
std::pair<std::unique_ptr<int>, std::unique_ptr<int>> wrapped_shallow_copy()
{
auto orig = shallow_copy();
std::pair<std::unique_ptr<int>, std::unique_ptr<int>> result;
result.first.reset(orig.first);
result.second.reset(orig.second);
return result;
}
Now, use wrapped_shallow_copy() instead of shallow_copy() and you will never leak memory from the call.

Error on adding to empty comboBox in Qt

I use Qt 5.2.0 (MSVC 2010).
I added to my form in Qt a ComboBox.
Then I want to fill it with numbers:
for (i = 0; i < n; i++){
ui->tableCombo->addItem(QString::number(i));
}
When I add a first element right in the form, it successfully adds numbers. But when I leave it empty, it throws an error:
ASSERT failure in QVector::operator[]: "index out of range"
Debugger shows that error occured right in this line. And there is no QVector across the line.
After adding qDebug().
qDebug() << "readFileToStringList: msg10";
for (i = 0; i < n; i++){
qDebug() << "readFileToStringList: msg20 i = " << i;
ui->tableCombo->addItem(QString::number(i+1));
qDebug() << "readFileToStringList: msg30";
}
qDebug() << "readFileToStringList: msg40";
I get the same result
readFileToStringList: msg10
readFileToStringList: msg20 i = 0
ASSERT failure in QVector<T>::operator[]: "index out of range", file C:\Qt\Qt5.2.0\5.2.0\mingw48_32\include/QtCore/qvector.h, line 369
I had this exact problem and couldn't figure it out for a couple hours. I realized ::addItem() was triggering the indexChanged(int) signal, which I had connected to a function that was causing an out-of-range error in a container.
I would say it was possibly the problem here too, but I'm sure the OP has moved on since then. To me it isn't exactly intuitive that the indexChanged signal would be called on insertion of new items, since it doesn't actually change the currentIndex.
Hopefully if anyone else gets tripped up this will help them!
addItem() doesn't throw that error! I'm positive it's coming from another instruction in your code.
Qt documentation has an entire section on Debugging Techniques, but if you are afraid of debuggers you can use the poor's man debugger: spread several qDebug() messages before and after the instructions you think are responsible for the problem:
qDebug() << "methodX: msg10";
for (i = 0; i < n; i++){
qDebug() << "methodX: msg20 i = " << i;
ui->tableCombo->addItem(QString::number(i));
qDebug() << "methodX: msg30";
}
qDebug() << "methodX: msg40";
If the message methodX: msg30 gets printed to the screen, means that addItem() didn't cause the error.

how to set/read QSqlRelationalTableModel column properties and constraints?

Is there any way to check properties and constraints for each column in a QSqlRelationalTableModel? For example, I'd like to ask my QSqlRelationalTableModel object whether a certain column can contain nulls, or what datatype is valid for that column.
You'll need to get a QSqlField value for each column of the model, which is given by
QSqlRecord record = model->database().record(model->tableName());
QSqlField field = record.field(columnIndex);
then you'll be able to check if a field can be null with QSqlField::requiredStatus() (if the driver supports querying that property) and to get its data type with QSqlField::type().
From alexisdm's answer above, I wrote this simple code snippet to output the properties of each field in a table. Posting it here to save typing for anyone else who is interested.
I also discovered a gotcha: if you use table_model::record() or table_model::record(int) you get unexpected (to me) results for some properties, e.g., isAutoValue seems to always return false, even for fields designated as autoincrement fields in the database. However, you do get a real value for typeID() (though I haven't been able to determine what typeID() is), whereas typeID() always returned -1 for me using model->database().record(model->tableName()).
QSqlRecord record = table_model->database().record(table_model->tableName());
// the following get isAutoValue() wrong; but have a real typeID()
//QSqlRecord record = table_model->record();
//QSqlRecord record = table_model->record(table_model->rowCount() - 1);
qDebug() << "********** table" << table_model->tableName() << "*********";
for (int i = 0; i < table_model->columnCount(); ++i) {
QSqlField field = record.field(i);
qDebug() << "---------- field" << i << field.name() << "--------";
qDebug() << "default value" << field.defaultValue();
qDebug() << "is auto value" << field.isAutoValue();
qDebug() << "is generated" << field.isGenerated();
qDebug() << "is null" << field.isNull();
qDebug() << "is read only" << field.isReadOnly();
qDebug() << "is valid" << field.isValid();
qDebug() << "length" << field.length();
qDebug() << "precision" << field.precision();
qDebug() << "required status" << field.requiredStatus();
qDebug() << "type" << field.type();
qDebug() << "type id" << field.typeID();
qDebug() << "value" << field.value();
}

Resources