Tests finish with exit code 139 (interrupted by signal 11: SIGSEGV) - c++

I'm a CS student and one of the classes I'm taking this semester requires me to complete different assignments (in C++) and then test them with unit-tests written by our professor.
Link to the repository with tests and the skeleton of the exercises
All of the tests form la1 worked just fine. Sadly most of them stopped working just as I started testing code from lab2 exercises. All the tests print the same message to the console:
Running main() from gtest_main.cc
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
Today, after I've completed the lab2->greatestproduct exercise
Given an array of integers, write a function, maxProductFinderK, that can be obtained from any k integers in the array.
I checked all of the tests by hand and the result I've gotten were all correct so I don't think my code is the real issue here.
Is there anything that I could double-check to solve this problem? So far I've tried:
creating new CMakeLists.txt file (I don't think that's the problem since I use a template to create them)
cloning the repository with exercises again
Using different solutions just to make sure the code itself is not the problem
I'm running all the tests in CLion (with the latest update) on MacOS 10.13.3 if that's relevant.
// Edit: just as requested I added the code here in case the link will stop working.
Solution to the assignment:
int GreatestProduct(const std::vector<int> &numbers, int k) {
if ( numbers.size() > 0) {
std::vector<int> largestK = numbers;
std::sort(largestK.begin(), largestK.end());
if (k == 0) {
return 0;
} else if (k == 1) {
return largestK.at(largestK.size() - 1);
}
largestK.erase(largestK.begin(), largestK.end() - (k)); // remove all but k largest elements
std::vector<int> smallestK = numbers;
std::sort(smallestK.begin(), smallestK.end());
smallestK.erase(smallestK.begin(),
smallestK.begin() + k - (k % 2)); // remove all but k-(k%2) smallest elements
int mustContain = (k % 2) * (largestK.at(0) - 1) + 1;
//make sure that largestK and smallestK are the same size
if (k % 2 != 0) {
largestK.erase(largestK.begin());
}
std::vector<int> final;
int currentLargest = 0;
int currentSmallest = 0;
int greatestProduct = 1;
while (currentLargest + currentSmallest < k - (k % 2)) {
int firstOption = largestK.at(currentLargest) * largestK.at(currentLargest + 1);
int secondOption = smallestK.at(currentSmallest) * smallestK.at(currentSmallest + 1);
if (mustContain * firstOption > mustContain * secondOption) {
final.push_back(firstOption);
currentLargest += 2;
} else {
final.push_back(secondOption);
currentSmallest += 2;
}
}
for (int element : final) {
greatestProduct *= element;
}
return greatestProduct;
} else {
return 0;
} }
First out of 3 test. This one's the easiest since it always assumes that k = 2 and it doesn't test negative integers.
#include <GreatestProduct.h>
#include <gtest/gtest.h>
#include <MemLeakTest.h>
#include <StringUtility.h>
using TestParam = std::pair<std::pair<std::vector<int>, int>, int>;
class GreatestProductOfStep1Tests : public ::testing::TestWithParam<TestParam>, MemLeakTest {
};
TEST_P(GreatestProductOfStep1Tests, GreatestProductOfPositiveNumbersNfixedTo2ShouldReturnExpectedResult) {
const TestParam &p = GetParam();
int expected = p.second;
const std::vector<int> &numbers = p.first.first;
int N = p.first.second;
EXPECT_EQ(expected, GreatestProduct(numbers, N))
<< "Did call GreatestProductOf(" << utility::ToString<int>(numbers) << ", " << N << ")\n";
}
std::vector<TestParam> greatest_product_test_positive_n_eq_2_data{
{{{0, 1, 2, 3, 4}, 2}, 12},
{{{6, 6, 6}, 2}, 36},
{{{9, 8, 3, 5, 8, 1, 3, 5, 10}, 2}, 90},
{{{17, 5, 9, 1000, 15689, 57, 89, 10, 89, 283, 197, 0, 0, 132, 45, 78, 18, 15, 89,
19203, 98, 14, 78, 45, 35, 23, 24, 25, 46, 45, 756, 7567, 123, 890, 99, 98, 51,
991, 9123, 8912, 89534, 8923, 1823, 7385, 91, 1748, 1, 1, 893, 2813,
1381, 23, 563, 645, 24, 24, 51, 839, 38, 34, 35, 123, 324, 9283, 22, 19}, 2}, 1719321402},
{{{1, 1}, 2}, 1},
{{{0, 1}, 2}, 0},
{{{3789, 999}, 2}, 3785211}};
INSTANTIATE_TEST_CASE_P(GreatestProductOfStep1Tests,
GreatestProductOfStep1Tests,
::testing::ValuesIn(greatest_product_test_positive_n_eq_2_data));

Related

How to access the values of a map<string, vector<int>> in C++?

I am working on my version of a genetic algorithm to solve the knapsack problem in C++. I have a map of string to vector like
map<string, vector<int>> objects
{
{"Object 1", {7, 20, 15}},
{"Object 2", {3, 50, 10}},
{"Object 3", {5, 80, 12}},
{"Object 4", {4, 80, 8}},
{"Object 5", {2, 40, 11}}
};
and a vector of vectors
vector<vector<int>> population;
where I will store information such as
population[0] = {0, 0, 1, 1, 0};
population[1] = {1, 0, 0, 0, 1};
population[2] = {1, 0, 1, 0, 1};
...
Each vector is called an individual, and each element of a given individual indicates the presence (1) or the absence (0) of the corresponding object. So, for example, the third individual (population[2]) has Object 1, Object 3 and Object 5.
What I want to do is write a function which will receive an index from population and return the sum of the corresponding values from objects. In the case of population[2] I'd like to have another vector containing {14, 140, 38} (7+5+2, 20+80+40, 15+12+11).
But I'm struggling to access the values of the objects map.
map<string, vector<int>> objects {/*...*/}
vector<vector<int>> population;
void initializePopulation() {/*...*/}
void getScore(vector<int> individual, vector<int>& sum)
{
for(int i = 0; i < 3; i++)
{
sum.push_back(0);
for(int j = 0; j < 5; j++)
{
if(individual[j] == 1)
{
sum[i] += ???;
}
}
}
int main()
{
/*...*/
initializePopulation();
vector<int> sum;
getScore(population[2], sum);
}
So, as you can see, I'm not sure how to proceed with sum[i]. Any suggestions? I'm not very fluent in C++, so a more detailed answer would be appreciated!
For both vector of vectors as well as a map, you can use for each loop!
When your map is filled with value
for(auto x: objects){
cout<<x.first<<" "<<x.second<<endl;
}
This will print key-value pairs in a map with space in between!
In this problem you'll have to iterate values (i.e. the second) in map too!
{"Object 1", {7, 20, 15}}
{"Object 2", {3, 50, 10}}
{"Object 3", {5, 80, 12}}
{"Object 4", {4, 80, 8}}}
{"Object 5", {2, 40, 11}}
For something like this the following code should work:
for(auto x: objects){
cout<<x.first<<" ";
for(auto y: x.second){
cout<<y<<" ";
}
cout<<endl;
}
For vector of vectors, you can use the same concept!
Try renaming Object 1, Object 2, .... to just 1,2, ....
This will allow you to access values in map by using j from your for loop!
For a more simplified version consider this prototype instead, since you are using words like population and genetic, I assume your data to be humungous, so you are better off using const reference while passing data around (const&, they won't be copied and will become read-only). global variable is a bad idea in general.
void getScore(map<string, vector<int>> const& objects, vector<int> const& individual, vector<int>& sum)
{
// iterate over each object for the individual
for(int i = 0; i < 5; i++)
{
// are you sure you want sum as {14, 140, 38} (7+5+2, 20+80+40, 15+12+11)
// not {14,0, 140,0, 38} (7+5+2, 0, 20+80+40, 0, 15+12+11)
// use else part for later
if(individual[i] == 1)
{
// compute sum for each object
// retrieve object vector
auto it = objects.find("KEY"); // KEY generation discussed later
if(it!=objects.end()){ // validate key :::: important
vector<int> ob = objects["KEY"]; //it->second
sum.push_back(std::accumulate(ob.begin(),ob.end(),0) ); // https://www.cplusplus.com/reference/numeric/accumulate/
}
} /*else {
sum.push_back(0);
}*/
}
}
KEY generation:
1). generating "Object 1" :
string key = "Object " + to_string(i+1)
auto it = objects.find(key);
2). suggested :
use integers as key
or
go with an enum like
enum ObjList{
OBJECT_1,
OBJECT_2,
OBJECT_3
}
auto it = objects.find(i); //mind your indexes
hope it helps, happy coding XD
I think that with some little linear algebra your problem has an easy solution: indeed, if you store the numerical data related to your objects into a matrix A, then for each population vector p your desired result is simply p^T A (or equivalently, A^T p) where ^T denotes the transpose of a matrix or of a vector.
If you are not planning to employ any linear algebra library, you could implement the scalar product by yourself. Down below there is the code implementing the above idea.
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <numeric>
std::vector<int> SP(std::vector<std::vector<int>> const &M, std::vector<int> const &P){
std::vector<int> sums(3,0);
// perform p^T * A operation
for (int j=0;j<3;j++)
for (int i=0;i<5;i++)
sums[j] += M[i][j] * P[i];
return sums;
}
int main(){
std::map<std::string, std::vector<int>> objects {
{"Object 1", {7, 20, 15}},
{"Object 2", {3, 50, 10}},
{"Object 3", {5, 80, 12}},
{"Object 4", {4, 80, 8}},
{"Object 5", {2, 40, 11}}
};
std::vector<std::vector<int>> population(3);
population[0] = {0, 0, 1, 1, 0};
population[1] = {1, 0, 0, 0, 1};
population[2] = {1, 0, 1, 0, 1};
std::vector<std::vector<int>> A;
// Extract the numerical data from the map
for (auto const& [key, val] : objects)
A.push_back(val);
// vector in which the desired values are stored for the 3rd element of the population
std::vector<int> s = SP(A,population[2]);
// Just for checking
for (int it=0; it<s.size(); it++)
std::cout << s[it] << std::endl;
return 0;
}

How to define a C++ function in VTK

I'm new with C++ and VTK. I'm trying to get cells ID into a rectilinearGrid basic example. I'm using this code, but the compiler say that is wrong with the error that I wrote in comment
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkFloatArray.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRectilinearGrid.h>
#include <vtkRectilinearGridGeometryFilter.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <array>
int main()
{
vtkNew<vtkNamedColors> colors;
std::array<int, 16> x = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
std::array<int, 16> y = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
std::array<int, 16> z = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
// Create a rectilinear grid by defining three arrays specifying the
// coordinates in the x-y-z directions.
vtkNew<vtkFloatArray> xCoords;
for (auto&& i : x)
{
xCoords->InsertNextValue(i);
}
vtkNew<vtkFloatArray> yCoords;
for (auto&& i : y)
{
yCoords->InsertNextValue(i);
}
vtkNew<vtkFloatArray> zCoords;
for (auto&& i : z)
{
zCoords->InsertNextValue(i);
}
// The coordinates are assigned to the rectilinear grid. Make sure that
// the number of values in each of the XCoordinates, YCoordinates,
// and ZCoordinates is equal to what is defined in SetDimensions().
//
vtkNew<vtkRectilinearGrid> rgrid;
rgrid->SetDimensions(int(x.size()), int(y.size()), int(z.size()));
rgrid->SetXCoordinates(xCoords);
rgrid->SetYCoordinates(yCoords);
rgrid->SetZCoordinates(zCoords);
vtkCell* GetCell(vtkRectilinearGrid * rgrid, int i, int j, int k) //I SHOULD INSERT IN HERE ";" FOR
{ //CLOSING THE STATEMENT. BUT IN
int dims[3]; //THIS WAY THE FUNCTION PARAMETER
rgrid->GetDimensions(dims); // BEHIND WOULDN'T BE CONNECTED.
if (i < 0 || i > dims[0] - 1 ||
j < 0 || j > dims[1] - 1 ||
k < 0 || k > dims[2] - 1)
{
return NULL; // out of bounds!
}
int pos[3];
pos[0] = i;
pos[1] = j;
pos[2] = k;
vtkIdType id;
id = vtkStructuredData::ComputeCellId(dims, pos);
return rgrid->GetCell(id);
};
// Extract a plane from the grid to see what we've got.
vtkNew<vtkRectilinearGridGeometryFilter> plane;
plane->SetInputData(rgrid);
plane->SetExtent(0, 46, 16, 16, 0, 43);
vtkNew<vtkPolyDataMapper> rgridMapper;
rgridMapper->SetInputConnection(plane->GetOutputPort());
vtkNew<vtkActor> wireActor;
wireActor->SetMapper(rgridMapper);
wireActor->GetProperty()->SetRepresentationToWireframe();
wireActor->GetProperty()->SetColor(colors->GetColor3d("Black").GetData());
// Create the usual rendering stuff.
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renderer->AddActor(wireActor);
renderer->SetBackground(1, 1, 1);
renderer->ResetCamera();
renderer->GetActiveCamera()->Elevation(30.0);
renderer->GetActiveCamera()->Azimuth(15.0);
renderer->GetActiveCamera()->Zoom(1.0);
renderer->SetBackground(colors->GetColor3d("Beige").GetData());
renWin->SetSize(600, 600);
// interact with data
renWin->Render();
iren->Start();
return EXIT_SUCCESS;
}
How could be fixed?
UPDATE 1: I have inserted an image of the compiling error. Should be inserted ";" for closing the statement before {}
UPDATE 2: the exact error is
Errore (attivo) E0065 expected ';' RGrid C:\vtk\VTK-8.2.0\Examples\DataManipulation\Cxx\RGrid.cxx 73
I'm using Visual Studio. I have tried to drop the last ";" but nothing change
UPDATE 3: I have uploaded all the code
You have defined your GetCell function inside the body of the main function, which is not allowed in C++. Only a declaration would be allowed inside the body, hence the compiler expects a semicolon after the function header.
Move the whole GetCell function block outside the main function. If that leads to problems you cannot solve ask another question about them.

Why does not gtest see the definition of ==?

I have a templated class Matrix:
template<typename T>
class Matrix {
//blah-blah-blah
}
And the following operator:
template<typename T>
bool operator==(const Matrixes::Matrix<T> &lhs, const Matrixes::Matrix<T> &rhs) {
if (lhs.get_cols()!=rhs.get_cols() || lhs.get_rows()!=rhs.get_rows()){
return false;
}
for (int r = 0; r < lhs.get_rows(); ++r) {
for (int c = 0; c < lhs.get_cols(); ++c) {
if (lhs.get(r, c) != rhs.get(r, c)) {
return false;
}
}
}
return true;
}
The aforementioned operator is defined outside the Matrixes namespace.
I have a few tests(I am using framework Google Tests). However, if I write something like:
TEST(MatrixOperations, MatrixMultiplicationSimple) {
Matrixes::Primitives<int>::VectorMatrix vec1{{{8, 3, 5, 3, 8}, {5, 2, 0, 5, 8}, {0, 3, 8, 8, 1}, {3, 0, 0, 5, 0}, {2, 7, 5, 9, 0}}};
Matrixes::Primitives<int>::VectorMatrix vec2{{{3, 1, 7, 2, 9}, {4, 6, 2, 4, 5}, {2, 5, 9, 4, 6}, {5, 3, 3, 1, 2}, {1, 8, 2, 6, 8}}};
Matrixes::Matrix<int> vec1m{vec1};
Matrixes::Matrix<int> vec2m{vec2};
Matrixes::Matrix<int> matrix_out_ref{{{69, 124, 132, 99, 187}, {56, 96, 70, 71, 129}, {69, 90, 104, 58, 87}, {34, 18, 36, 11, 37}, {89, 96, 100, 61, 101}}};
Matrixes::Matrix<int> matrix_out_fact = vec1m * vec2m;
bool t = matrix_out_fact == matrix_out_ref;
EXPECT_EQ(t, true);
}
everything works fine. Note, that I'm using operator== "manually" here:
bool t = matrix_out_fact == matrix_out_ref;
EXPECT_EQ(t, true);
However, if instead of these two lines I write something like:
EXPECT_EQ(matrix_ou_fact, matrix_out_ref);
I get the compilation error:
/usr/local/include/gtest/gtest.h:1522:11: error: no match for ‘operator==’ (operand types are ‘const Matrixes::Matrix<int>’ and ‘const Matrixes::Matrix<int>’)
if (lhs == rhs) {
Why doesn't gtest "see" the definition of operator==?
Thanks
The comparison inside EXPECT_EQ happens in a different scope than your immediate test case. It looks up the operator function it needs to call via argument dependent lookup(ADL). Because your operator function is not in the same namespace as your class, it is not picked up by ADL.
It works inside your immediate test case because you probably include the appropriate headers in the appropriate order, so that finding the operator does not rely on ADL. But the implementation of the Gtest framework has to rely on ADL.
So the fix is easy. Move your custom operator into the Matrixes namespace. It's part of your class's public interface, so it belongs in the same namespace anyway.

illegal, left operand has type 'DWORD [29]'

I'm pretty new to C++ and I'm really stuck here.
if (bAk == 1)
{
int fireRate = 134;
if (shotTiming < 30)
{
int valueX = (AssaultRifle::recoilTableX[shotTiming] * 0.48) + shakerNum;
int smoothingX = valueX / 5;
int valueY = (AssaultRifle::recoilTableY[shotTiming] * 0.48) + shakerNum;
int smoothingY = valueY / 5;
Sleep(3);
for (int i = 0; i < 5; i++)
{
mouse_move(valueX, valueY);
Sleep(fireRate / 5);
}
shotTiming++;
cout << valueX;
}
}
The only build error I am getting at this point is illegal, left operand has type 'DWORD [29]' Both int values of recoilTable are saying that the AssaultRifle namespace must have arithmetic or unscoped enum type. I just need to be put in the right direction of finishing it.
#pragma once
#include <Windows.h>
namespace AssaultRifle
{
const size_t MAX_INDEX_WEAPON = 1;
const size_t MAX_INDEX_RECOIL = 29;
DWORD recoilTableY[MAX_INDEX_WEAPON][MAX_INDEX_RECOIL] = {
{ 40, 48, 48, 48, 33, 33, 28, 24, 16, 13, 18, 22, 24, 29, 33, 33, 33, 29, 22, 20, 17, 17, 17, 17, 20, 27, 27, 27, 26 }
};
DWORD recoilTableX[MAX_INDEX_WEAPON][MAX_INDEX_RECOIL] = {
{ -36, 5, -59, -49, 3, 20, 25, 45, 43, 32, 82, 8, 43, -32, -25, -40, -35, -32, -43 , -42, -42, -55, -25, 15, 20, 35, 50, 62, 40 }
};
}
Your recoilTableX and recoilTableY arrays are both 2-dimensional 1:
DWORD recoilTableY[<# elements in first dimension>][<# elements in second dimension>] = {...};
DWORD recoilTableX[<# elements in first dimension>][<# elements in second dimension>] = {...};
But when reading individual values from the arrays, your code is indexing into only the first dimension. That is why you are getting the error, as you can't access an entire array as a single integer like you are attempting to do. You have to specify indexes for ALL of the available dimensions.
Change this:
AssaultRifle::recoilTableX[shotTiming]
AssaultRifle::recoilTableY[shotTiming]
To this instead:
AssaultRifle::recoilTableX[0][shotTiming]
AssaultRifle::recoilTableY[0][shotTiming]
MAX_INDEX_WEAPON is 1, so there is only 1 slot in the first dimension of the arrays, so the ONLY valid index in the first dimension is 0, which makes the first dimension pretty useless and should be removed, unless you are planning on adding values for additional weapons in the future.
MAX_INDEX_RECOIL is 29, so there are 29 slots in the second dimension of the arrays, so the ONLY valid indexes in the second dimension are 0..28 inclusive, but your code allows index 29 to be accessed.
The NAMES of your MAX_INDEX_WEAPON and MAX_INDEX_RECOIL constants are misleading, as they are not actually being used as indexes at all.
1: also, your arrays should be declared as const.
Try this instead:
#pragma once
#include <Windows.h>
namespace AssaultRifle
{
const size_t MAX_WEAPONS = 1;
const size_t MAX_RECOILS = 29;
const int recoilTableY[MAX_WEAPONS][MAX_RECOILS] = {
{ { 40, 48, 48, 48, 33, 33, 28, 24, 16, 13, 18, 22, 24, 29, 33, 33, 33, 29, 22, 20, 17, 17, 17, 17, 20, 27, 27, 27, 26 } }
};
const int recoilTableX[MAX_WEAPONS][MAX_RECOILS] = {
{ { -36, 5, -59, -49, 3, 20, 25, 45, 43, 32, 82, 8, 43, -32, -25, -40, -35, -32, -43 , -42, -42, -55, -25, 15, 20, 35, 50, 62, 40 } }
};
}
if (bAk == 1)
{
int fireRate = 134;
if (shotTiming < AssaultRifle::MAX_RECOILS)
{
int valueX = (AssaultRifle::recoilTableX[0][shotTiming] * 0.48) + shakerNum;
int smoothingX = valueX / 5;
int valueY = (AssaultRifle::recoilTableY[0][shotTiming] * 0.48) + shakerNum;
int smoothingY = valueY / 5;
Sleep(3);
for (int i = 0; i < 5; i++)
{
mouse_move(valueX, valueY);
Sleep(fireRate / 5);
}
shotTiming++;
cout << valueX;
}
}

lock free concurrency example; why is it not safe?

I am trying to learn about concurrency in C++ and in doing so I am experimenting to see what works and what does not work. The example below is not well designed and I know there are much better ways of designing it but I would like to know why it seems that thread 1 and thread 2 are able to overwrite each other in the shared array. I thought the operations to the shared flag_atomic variable with the acquire/release semantics above and below the loading and writing of the shared idx_atomic index would prevent thread 1 and thread 2 retrieving the same index values regardless of the idx_atomic operation memory tags?
For reference I am using MSVC and x64.
#include <iostream>
#include <vector>
#include <atomic>
#include <thread>
#include <chrono>
using namespace std::chrono; // for ""ms operator
const size_t c_size = 40;
std::vector<int> shared_array;
std::atomic<bool> sync_start_atomic = false;
std::atomic<bool> flag_atomic = false;
std::atomic<size_t> idx_atomic = 0;
void thread1_x() {
bool expected_flag = false;
size_t temp_idx = 0;
while (!sync_start_atomic.load(std::memory_order_relaxed));
for (size_t i = 0; i < (c_size / 2); ++i) {
while (flag_atomic.compare_exchange_weak(expected_flag, true, std::memory_order_acq_rel, std::memory_order_acquire)) {
expected_flag = false;
}
temp_idx = idx_atomic.load(std::memory_order_relaxed);
idx_atomic.store((temp_idx + 1), std::memory_order_relaxed);
flag_atomic.store(false, std::memory_order_release);
shared_array[temp_idx] = i;
}
}
void thread2_x() {
bool expected_flag = false;
size_t temp_idx = 0;
while (!sync_start_atomic.load(std::memory_order_relaxed));
for (size_t i = 0; i < (c_size / 2); ++i) {
while (flag_atomic.compare_exchange_weak(expected_flag, true, std::memory_order_acq_rel, std::memory_order_acquire)) {
expected_flag = false;
}
temp_idx = idx_atomic.load(std::memory_order_relaxed);
idx_atomic.store((temp_idx + 1), std::memory_order_relaxed);
flag_atomic.store(false, std::memory_order_release);
shared_array[temp_idx] = i + 100;
}
}
void main(){
shared_array.reserve(c_size);
shared_array.assign(c_size, 0);
std::thread tn_1(thread1_x);
std::thread tn_2(thread2_x);
std::this_thread::sleep_for(60ms);
sync_start_atomic.store(true, std::memory_order_relaxed);
tn_1.join();
tn_2.join();
for (size_t i = 0; i < c_size; ++i) {
std::cout << shared_array[i] << " ";
}
std::cout << "\n";
}
Example real output:
100, 1, 101, 2, 3, 102, 4, 103, 104, 6, 106, 8, 108, 9, 10, 109, 11, 110, 12, 111, 14, 112, 113, 16, 17, 18, 115, 19, 116, 117, 118, 119, 0, 0, 0, 0, 0, 0, 0, 0.
Example expected output:
0, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 1, 2, 114, 3, 115, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 116, 16, 117, 17, 118, 18, 119, 19.
Your example output indicates that both threads are accessing the idx_atomic concurrently, which indicates a problem with your flag_atomic loop. The condition check you are using is backwards. compare_exchange_weak will return the result of the flag_atomic == expected_flag comparison - in other words, it returns true when the value is updated. Since you want to exit the loop when this happens, the comparison should be
while (!flag_atomic.compare_exchange_weak(expected_flag, true, std::memory_order_acq_rel, std::memory_order_acquire))