问题 (std::bad_alloc) 通过 QThread 中的 QSqlQuery 将大图像(约 36 MB)保存到
Problem (std::bad_alloc) saving large image (about 36 mb) to postgres DB via QSqlQuery in QThread
我在尝试保存相对较大(~36 mb)的图像时遇到QSqlQuery问题。当我调用QSqlQuery::exec()时,我得到std::bad_alloc exeption。当我处理较小的图像时,一切都很好。 需要说的是 - 此代码在QThread的其他实例中执行,以防止GUI冻结,所有代码均在MinGW-32编译器中编译,PC上有8 GB RAM。有时(很少)即使使用这种大小的图像(36 mb),我也会运行此代码而没有此异常
这是代码:
......
QByteArray byte_array_image, byte_array_icon;
QBuffer buffer_image(&byte_array_image), buffer_icon(&byte_array_icon);
buffer_image.open(QIODevice::WriteOnly);
buffer_icon.open(QIODevice::WriteOnly);
image->save(&buffer_image, format.toLocal8Bit().data());
icon->save(&buffer_icon, "JPEG");
query.prepare("INSERT INTO pictures (id, id_act, date_time, name, picture, icon) VALUES (:id, :id_act, :date_time, :name, :picture, :icon)");
......
query.bindValue(":picture", byte_array_image);
query.bindValue(":icon", byte_array_icon);
byte_array_image.clear();
byte_array_icon.clear();
save_succeed = query.exec();
if (!save_succeed)
emit database_failed(QUERY_ERROR_HEADER, QUERY_ERROR_SAVE_IMAGE + query.lastError().text());
emit query_finished();
return save_succeed;
据我所知,问题可能与QApplication创建QString实例的堆空间不足有关,包括图像的所有字节码。为了解决这个问题,我试图将此图像分成十个部分,但这无济于事。
下面是由十个部分拆分的查询代码:
............
QByteArray byte_array_image, byte_array_icon;
QBuffer buffer_image(&byte_array_image), buffer_icon(&byte_array_icon);
buffer_image.open(QIODevice::WriteOnly);
buffer_icon.open(QIODevice::WriteOnly);
image->save(&buffer_image, format.toLocal8Bit().data());
icon->save(&buffer_icon, "JPEG");
int partlen, parts_count = 0;
save_succeed = false;
while (!save_succeed && ++parts_count < 10)
{
partlen = byte_array_image.size();
partlen = byte_array_image.size() / parts_count;
query.clear();
query.prepare("INSERT INTO pictures (id, id_act, date_time, name, part_one, parts_count, icon, src, src_act) "
"VALUES (:id, :id_act, :date_time, :name, :part_one, :parts_count, :icon, :src, :src_act)");
........
query.bindValue(":part_one", byte_array_image.mid(0, partlen));
query.bindValue(":parts_count", parts_count);
query.bindValue(":icon", byte_array_icon);
try
{
save_succeed = query.exec();
}
catch (std::bad_alloc &error)
{
if (parts_count < 10)
continue;
emit database_failed(QUERY_HEAP_ERROR_HEADER, QUERY_HEAP_ERROR_TEXT);
return false;
}
}
if (save_succeed)
{
QStringList part_names = { "part_one", "part_two", "part_three", "part_four", "part_five",
"part_six", "part_seven", "part_eight", "part_nine", "part_ten"};
for (int current_part = 1; current_part < parts_count; ++current_part)
{
query.clear();
query.prepare("UPDATE pictures SET "+part_names[current_part]+" = :current_part WHERE id = :id AND src = :src");
query.bindValue(":current_part", current_part == parts_count - 1 ? byte_array_image.mid(current_part*partlen) : byte_array_image.mid(current_part*partlen, partlen));
........
save_succeed = query.exec();
}
}
byte_array_image.clear();
byte_array_icon.clear();
我对问题来源是否正确?我能做些什么来修复它吗?图像的36 MB并不多。
1) 尝试编辑您的postgresql.conf
- 这可能是数据库内存限制,而不是您的应用程序。有小的默认值,大约 20Mb 的共享缓冲区。使用此链接作为示例 https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server
2)要检查这是数据库还是您的问题,在exec
之前,请尝试分配并释放大内存bffer - 比请求的图像大几倍。如果正常并且exec
抛出内存异常,则问题出在数据库或驱动程序上,而不是您的应用程序。
3)您也可以在调试器下进入该exec
,并观察bad_alloc
发生在哪里
相关文章:
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 平均图像时图像损坏
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- 使用FFMPEG将RGB图像序列保存到.mp4时出现问题
- 将RGB图像保存为PPM格式
- 将图像添加到资源文件夹UWP C++
- 彩色图像的卤化物处理平均值
- C++射线示踪剂ppm表示没有足够的数据来显示图像
- 重新定位图像时如何前进到下一个内存块
- 如何使用按钮更新GTK3图像以使用C++从相机捕获图片
- 为什么 BMP 图像上的 imwrite 会卡住/不返回?
- Gstreamer:每 5 秒使用多文件墨水保存图像/jpeg
- 如何使用CImg打开图像?
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- 问题 (std::bad_alloc) 通过 QThread 中的 QSqlQuery 将大图像(约 36 MB)保存到