Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
152 views
in Technique[技术] by (71.8m points)

c++ - Pass thread arguments by reference gives me access violation

I looked up how I can pass thread arguments by reference and I found std::ref so I used that:

void Watermarker::markDirectory(const std::string& targetDirectory, const std::string& watermarkPath)
{
    std::vector<std::thread*> threads;

    cv::Mat watermarkImage = loadImage(watermarkPath);
    if (watermarkImage.data == NULL) { return; }

    // Loop through all the files in the target directory
    for (const std::filesystem::path& path : std::filesystem::directory_iterator(targetDirectory))
    {
        std::thread* thread = new std::thread(mark, std::ref(targetDirectory), std::ref(path), std::ref(watermarkImage));
        threads.push_back(thread);
    }

    for (std::thread* thread : threads)
    {
        thread->join();
        delete thread;
    }
}

This is the function:

void Watermarker::mark(const std::string& targetDirectory, const std::filesystem::path& imagePath, cv::Mat& watermarkImage)
{
    cv::Mat image = loadImage(imagePath.string());
    if (image.data == NULL) { return; }

    cv::resize(watermarkImage, watermarkImage, image.size());

    // Give the images 4 channels
    cv::cvtColor(image, image, cv::COLOR_RGB2RGBA);
    cv::cvtColor(watermarkImage, watermarkImage, cv::COLOR_RGB2RGBA);

    // Add the watermark to the original image
    cv::addWeighted(watermarkImage, 0.3, image, 1, 0.0, image);

    saveImage(targetDirectory + "/watermarked_images/" + imagePath.filename().string(), image);
}

But when I run this it throws an exception "Access violation writing location. I get these 2 popups: enter image description here

Without the std::ref and & in the function it works fine if I pass it by value, but I want it by reference.

question from:https://stackoverflow.com/questions/66054774/pass-thread-arguments-by-reference-gives-me-access-violation

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is that you're changing watermarkImage from multiple threads at once in the mark function, making your program have undefined behavior.

Suggestion: Take it as a const& and copy it in the thread.

void Watermarker::mark(const std::string& targetDirectory,
                       const std::filesystem::path& imagePath,
                       const cv::Mat& temp_watermarkImage)   // const added
{
    cv::Mat watermarkImage = temp_watermarkImage;       // make a local copy
    ...
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...