GDK代码赋值触发GCC‘Expression must be a modifiable value’错误原因排查
错误原因及修正方案
核心错误原因
GdkPixbuf是基于GObject框架的类型,这类对象天生不支持直接的值拷贝与赋值操作。GObject的设计核心是通过引用计数管理对象生命周期,它的拷贝构造函数和赋值运算符要么被显式删除,要么默认生成的版本无法正确处理引用计数逻辑,这就导致编译器判定images[i]是不可修改的左值,最终抛出expression must be a modifiable value错误。
另外你的代码还存在隐藏内存泄漏问题:gdk_pixbuf_new_from_file返回的是堆上分配的GdkPixbuf指针,直接解引用赋值会让原指针指向的内存无法被释放,同时新对象的生命周期也得不到正确管理。
修正方案
你需要改用指针或GObject的引用计数包装类型来存储图片对象,以下是两种可行方案:
方案1:使用原始指针(需手动管理内存)
void test_function(std::vector<GdkPixbuf*> &images) { std::vector<std::filesystem::path> filenames = {"path/a", "path/b"}; // 先清理原有指针,避免内存泄漏 for(auto pixbuf : images) { if(pixbuf) g_object_unref(pixbuf); } images.clear(); for(const auto& filename : filenames) { GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(filename.string().c_str(), NULL); if(pixbuf) { // 必须判断图片是否加载成功 images.push_back(pixbuf); } } } // 注意:使用完vector内的指针后,需逐个调用g_object_unref释放内存
方案2:使用Glib智能指针(推荐,自动管理生命周期)
如果使用GTKmm(GTK的C++绑定库),可以用glib::RefPtr自动处理引用计数,无需手动管理内存:
#include <glibmm/refptr.h> #include <gdkmm/pixbuf.h> void test_function(std::vector<Glib::RefPtr<Gdk::Pixbuf>> &images) { std::vector<std::filesystem::path> filenames = {"path/a", "path/b"}; images.clear(); for(const auto& filename : filenames) { try { auto pixbuf = Gdk::Pixbuf::create_from_file(filename.string()); images.push_back(pixbuf); } catch(const Glib::Error& e) { // 处理图片加载失败的情况 std::cerr << "加载图片失败:" << e.what() << std::endl; } } }
内容的提问来源于stack exchange,提问作者agamendon
相关产品推荐
相关产品推荐

