You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:31:03