<p>I found out what was wrong. It wasn't related to multithreading at all.
I was taking in a vector in a constructor <code>hitable_list(std::vector&lt;hitable*&gt; listVector)</code> and using a pointer to the first element of the vector elsewhere. So as soon as the vector went out of scope the pointer became invalid.</p>

<p>To solve this issue I just removed this constructor and whenever I need to pass in a vector I make sure that the vector stays in scope always and directly pass in the pointer to the first element of the vector, and it's size.</p>

CC BY-SA 4.0
2019-12-18T20:41:28.847Z
2019-12-18T20:41:28.847Z
Karthik
<p>I'm trying to make the path tracer shown in the Ray Tracing in One Weekend series multithreaded.</p>

<p>Here's the starting of my main function:</p>

<pre><code>//scene setup
    hitable* world = cornell_box();
    auto start = std::chrono::high_resolution_clock::now();
    light_hitable_list = hitable_list(lightsVector);
    string filePath = "img.png";

    Image image(nx, ny);
    TilePool tilePool(nx, ny, 50);

    //maxThreads = std::thread::hardware_concurrency();
    maxThreads = 1;
    std::vector&lt;std::thread&gt; renderThreads;
    renderThreads.resize(maxThreads);

    //RenderSettings renderSettings{world, &amp;image, &amp;tilePool, ns, BLACK_SKY, false, "img.png"};

    for (unsigned int i = 0; i &lt; maxThreads; i++)
    {
        renderThreads[i] = std::thread(&amp;renderScene, world, &amp;image, &amp;tilePool);
    }
    for (unsigned int i = 0; i &lt; maxThreads; i++)
    {
        if (renderThreads[i].joinable())
        {
            renderThreads[i].join();
        }
    }
</code></pre>

<p>And here's the renderScene function:</p>

<pre><code>void renderScene(hitable* world, Image* image, TilePool* tilePool) {

    while (tilePool-&gt;getPoolSize() &gt; 0)
    {   
        Tile tile = tilePool-&gt;getNextTile();

        for (int j = tile.yMax - 1; j &gt;= tile.yMin; j--) {

            for (int i = tile.xMin; i &lt; tile.xMax; i++) {
                vec3 col(0, 0, 0);
                for (int s = 0; s &lt; ns; s++) {
                    float u = (float(i) + random_number()) / float(nx);
                    float v = (float(j) + random_number()) / float(ny);

                    ray r = cam.get_ray(u, v);
                    vec3 p = r.point_at_parameter(2.0);
                    col += de_nan(color(r, world, &amp;light_hitable_list, 0));
                }
                col /= float(ns);
                col = vec3(sqrt(col[0]), sqrt(col[1]), sqrt(col[2]));

                (*image)[3 * i + 3 * nx * (ny - 1 - j)] = col[0];
                (*image)[3 * i + 3 * nx * (ny - 1 - j) + 1] = col[1];
                (*image)[3 * i + 3 * nx * (ny - 1 - j) + 2] = col[2];

            }

        }
    }
}
</code></pre>

<p>If I run the code above as it is I get this error:</p>

<blockquote>
  <p>Exception thrown at 0x00007FF70F601F2E in raytracer.exe: 0xC0000005:
  Access violation reading location 0x000001C200000190.</p>
</blockquote>

<p>here: <a href="https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/objects/hitables/hitable_list.h#L29" rel="nofollow noreferrer">https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/objects/hitables/hitable_list.h#L29</a></p>

<p>And instead of using just 1 thread if I use <code>maxThreads = std::thread::hardware_concurrency();</code></p>

<p>I get this error:</p>

<blockquote>
  <p>Exception thrown at 0x00007FF79DE01FCE in raytracer.exe: 0xC0000005:
  Access violation reading location 0x0000015E0000012C.</p>
</blockquote>

<p>here: <a href="https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/objects/hitables/hitable_list.h#L38" rel="nofollow noreferrer">https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/objects/hitables/hitable_list.h#L38</a></p>

<p>These errors are not for the parameters passed into the function. I have checked if they are NULL. It seems to be for the function call.
I'm completely new to multithreaded programming. But it doesn't feel like the error might be due to multithreading because I get such an error even while using <code>maxThreads = 1</code>. </p>

<p>Instead of the cornell box scene if I use the <code>model_scene</code> defined here: <a href="https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/Source.cpp#L135" rel="nofollow noreferrer">https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/Source.cpp#L135</a> sometimes I get the same error as above and sometimes it randomly starts working even with more than one threads.</p>

<p>Can someone please shed light as to why this might be occuring and what points should I keep in mind while writing a multithreaded path tracer?</p>

<pathtracing><multithreading>
Trouble making path tracer multithreaded, read access violation
Karthik
# Trouble making path tracer multithreaded, read access violation

(Asked by: username_0 on 2019-12-17)

I'm trying to make the path tracer shown in the Ray Tracing in One Weekend series multithreaded.

Here's the starting of my main function:

```
//scene setup
    hitable* world = cornell_box();
    auto start = std::chrono::high_resolution_clock::now();
    light_hitable_list = hitable_list(lightsVector);
    string filePath = "img.png";

    Image image(nx, ny);
    TilePool tilePool(nx, ny, 50);

    //maxThreads = std::thread::hardware_concurrency();
    maxThreads = 1;
    std::vector<std::thread> renderThreads;
    renderThreads.resize(maxThreads);

    //RenderSettings renderSettings{world, &image, &tilePool, ns, BLACK_SKY, false, "img.png"};

    for (unsigned int i = 0; i < maxThreads; i++)
    {
        renderThreads[i] = std::thread(&renderScene, world, &image, &tilePool);
    }
    for (unsigned int i = 0; i < maxThreads; i++)
    {
        if (renderThreads[i].joinable())
        {
            renderThreads[i].join();
        }
    }

```

And here's the renderScene function:

```
void renderScene(hitable* world, Image* image, TilePool* tilePool) {

    while (tilePool->getPoolSize() > 0)
    {   
        Tile tile = tilePool->getNextTile();

        for (int j = tile.yMax - 1; j >= tile.yMin; j--) {

            for (int i = tile.xMin; i < tile.xMax; i++) {
                vec3 col(0, 0, 0);
                for (int s = 0; s < ns; s++) {
                    float u = (float(i) + random_number()) / float(nx);
                    float v = (float(j) + random_number()) / float(ny);

                    ray r = cam.get_ray(u, v);
                    vec3 p = r.point_at_parameter(2.0);
                    col += de_nan(color(r, world, &light_hitable_list, 0));
                }
                col /= float(ns);
                col = vec3(sqrt(col[0]), sqrt(col[1]), sqrt(col[2]));

                (*image)[3 * i + 3 * nx * (ny - 1 - j)] = col[0];
                (*image)[3 * i + 3 * nx * (ny - 1 - j) + 1] = col[1];
                (*image)[3 * i + 3 * nx * (ny - 1 - j) + 2] = col[2];

            }

        }
    }
}

```

If I run the code above as it is I get this error:

> Exception thrown at 0x00007FF70F601F2E in raytracer.exe: 0xC0000005:
> Access violation reading location 0x000001C200000190.

here: <https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/objects/hitables/hitable_list.h#L29>

And instead of using just 1 thread if I use `maxThreads = std::thread::hardware_concurrency();`

I get this error:

> Exception thrown at 0x00007FF79DE01FCE in raytracer.exe: 0xC0000005:
> Access violation reading location 0x0000015E0000012C.

here: <https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/objects/hitables/hitable_list.h#L38>

These errors are not for the parameters passed into the function. I have checked if they are NULL. It seems to be for the function call.
I'm completely new to multithreaded programming. But it doesn't feel like the error might be due to multithreading because I get such an error even while using `maxThreads = 1`.

Instead of the cornell box scene if I use the `model_scene` defined here: <https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/Source.cpp#L135> sometimes I get the same error as above and sometimes it randomly starts working even with more than one threads.

Can someone please shed light as to why this might be occuring and what points should I keep in mind while writing a multithreaded path tracer?

**Tags:** pathtracing, multithreading


---

## 1 answers

### Answer by username_0 on 2019-12-18. Score: 0 | Accepted answer

I found out what was wrong. It wasn't related to multithreading at all.
I was taking in a vector in a constructor `hitable_list(std::vector<hitable*> listVector)` and using a pointer to the first element of the vector elsewhere. So as soon as the vector went out of scope the pointer became invalid.

To solve this issue I just removed this constructor and whenever I need to pass in a vector I make sure that the vector stays in scope always and directly pass in the pointer to the first element of the vector, and it's size.


---

