All pushed back values in vector changing to default value - c++

In an effort to reduce multiple functions (that were nearly identical) in my code, I decided to consolidate them all into one function which takes an additional parameter (a class with multiple parameters, actually), and then uses those values to imitate what the multiple functions would have done. Then, long story short, I put each of those class declarations into a vector, and now my program seems dysfunctional.
My multiple instances of a class:
FragmentCostParameters commonFCP = FragmentCostParameters(.05, 0);
FragmentCostParameters rareFCP = FragmentCostParameters(.05, 50);
FragmentCostParameters uniqueFCP = FragmentCostParameters(.05, 125);
FragmentCostParameters legendaryFCP = FragmentCostParameters(.02, 175);
FragmentCostParameters crystallineFCP = FragmentCostParameters(.02, 250);
FragmentCostParameters superEliteFCP = FragmentCostParameters(.02, 300);
Which get placed into a vector by:
vector<FragmentCostParameters> FCPs(6);
FCPs.push_back(FragmentCostParameters(.05, 0));
FCPs.push_back(FragmentCostParameters(.05, 50));
FCPs.push_back(FragmentCostParameters(.05, 125));
FCPs.push_back(FragmentCostParameters(.02, 175));
FCPs.push_back(FragmentCostParameters(.02, 250));
FCPs.push_back(FragmentCostParameters(.02, 300));
Additionally, that class is defined below:
class FragmentCostParameters {
public:
double multFactor;
double subtractFactor;
FragmentCostParameters(double _multFactor, double _subtractFactor){
multFactor = _multFactor;
subtractFactor = _subtractFactor;
}
FragmentCostParameters(){
multFactor = .05;
subtractFactor = 0;
}
};
Now, you'll notice that the default constructor for the FragmentCostParameters involves setting multFactor = .05 and subtractFactor = 0. However, it seems that no matter what I push back, each of the values in my vector become mutated into those values. At least, that's what VS 2011 tells me the values are equal to when I'm looking at them in a local scope in the following function (which is the only place they're used).
int FragmentCost(double skillLevel, int duration, FragmentCostParameters FCP){
return max((int)(ceil(FCP.multFactor*(skillLevel-FCP.subtractFactor))*ceil(duration/30.0)) , 0);
}
And the only place that FragmentCost is called is from this function below, which is supposed to pass different values .. but somewhere in the process, when I look at locals in FragmentCost, they're always the default values in the constructor for the class.
//given a skill level + duration, will return an array with the fragment usage
int* regularTotalFragCost(int skillLevel, int duration){
int fragments[7] = {0,0,0,0,0,0,0};
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[0]);
fragments[1]+= FragmentCost(skillLevel,duration, FCPs[0]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[1]);
fragments[2]+= FragmentCost(skillLevel,duration, FCPs[1]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[2]);
fragments[3]+= FragmentCost(skillLevel,duration, FCPs[2]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[3]);
fragments[4]+= FragmentCost(skillLevel,duration, FCPs[3]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[4]);
fragments[5]+= FragmentCost(skillLevel,duration, FCPs[4]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[5]);
fragments[6]+= FragmentCost(skillLevel,duration, FCPs[5]);
return fragments;
}
For some reason I feel that I'm making a really stupid mistake somewhere, but for the life of me I can't seem to figure it out. I would appreciate any help and/or advice anyone could offer.
EDIT: Here's what the values for fragments[] in regularTotalFragCost are supposed to be if everything is working correctly, using a couple test values (skillLevel = 250 and duration = 30)
FCPs[0] : Fragments: 13, 13, 0, 0, 0, 0, 0,
FCPs[1] : Fragments: 17, 15, 2, 0, 0, 0, 0,
FCPs[2] : Fragments: 20, 14, 5, 1, 0, 0, 0,
FCPs[3] : Fragments: 29, 14, 9, 5, 1, 0, 0,
FCPs[4] : Fragments: 32, 13, 10, 7, 2, 0, 0,
FCPs[5] : Fragments: 32, 13, 10, 7, 2, 0, 0,
And here is what they are as of right now:
FCPs[0] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[1] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[2] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[3] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[4] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[5] : Fragments: 78, 13, 13, 13, 13, 13, 13,

vector<FragmentCostParameters> FCPs(6);
creates a vector of 6 default-constructed values, numbered 0-5.
FCPs.push_back(FragmentCostParameters(.05, 0));
adds value at index 6

int fragments[7] is a local variable on the stack. Once that function returns, that memory is no longer valid. You are returning a pointer to that local variable and any access to that memory is undefined behavior.
Instead, return an std::array:
std::array<int, 7> fragments = {}; // value initialize
return fragments;

Hint: How big is your vector after you push_back your FCPs?

Related

How to assign value to dart enum like in c++

I'm trying to adapt a c++ to dart, and I ran into this situation with enum, assigning default values ​​I think. follow the code
enum skills_t : uint8_t {
SKILL_FIST = 0,
SKILL_CLUB = 1,
SKILL_SWORD = 2,
SKILL_AXE = 3,
SKILL_DISTANCE = 4,
SKILL_SHIELD = 5,
SKILL_FISHING = 6,
SKILL_CRITICAL_HIT_CHANCE = 7,
SKILL_CRITICAL_HIT_DAMAGE = 8,
SKILL_LIFE_LEECH_CHANCE = 9,
SKILL_LIFE_LEECH_AMOUNT = 10,
SKILL_MANA_LEECH_CHANCE = 11,
SKILL_MANA_LEECH_AMOUNT = 12,
SKILL_MAGLEVEL = 13,
SKILL_LEVEL = 14,
SKILL_FIRST = SKILL_FIST,
SKILL_LAST = SKILL_MANA_LEECH_AMOUNT
};
}
uint32_t skillBase[SKILL_LAST + 1] = {50, 50, 50, 50, 30, 100, 20};
Is it possible to adapt this code to dart/flutter?
I would like to replicate the same operation in dart, it seems that he assigned these values ​​to each enum in a range
Yes, it is possible to adapt this code to Dart/Flutter.
In Dart, you can use the enum keyword to define an enumeration. The syntax is similar to C++, but there is no need to specify a type like uint8_t.
Regarding the default values, you can initialize the enum members with a value like in C++.
Here is an example of how the C++ code could be adapted to Dart:
enum Skills {
FIST,
CLUB,
SWORD,
AXE,
DISTANCE,
SHIELD,
FISHING,
CRITICAL_HIT_CHANCE,
CRITICAL_HIT_DAMAGE,
LIFE_LEECH_CHANCE,
LIFE_LEECH_AMOUNT,
MANA_LEECH_CHANCE,
MANA_LEECH_AMOUNT,
MAGLEVEL,
LEVEL,
FIRST = FIST,
LAST = MANA_LEECH_AMOUNT,
}
final List<int> skillBase = [
50, 50, 50, 50, 30, 100, 20
];
You can also use a Map to assign the default values to each enum member.
enum Skills {
FIST,
CLUB,
SWORD,
AXE,
DISTANCE,
SHIELD,
FISHING,
CRITICAL_HIT_CHANCE,
CRITICAL_HIT_DAMAGE,
LIFE_LEECH_CHANCE,
LIFE_LEECH_AMOUNT,
MANA_LEECH_CHANCE,
MANA_LEECH_AMOUNT,
MAGLEVEL,
LEVEL,
FIRST = FIST,
LAST = MANA_LEECH_AMOUNT,
}
final Map<Skills, int> skillBase = {
Skills.FIST: 50,
Skills.CLUB: 50,
Skills.SWORD: 50,
Skills.AXE: 50,
Skills.DISTANCE: 30,
Skills.SHIELD: 100,
Skills.FISHING: 20,
// Add the rest of the skills
};
Both the above examples will work fine in dart/flutter.

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))

QwtPlotCurve doesn't show up on graph

I'm currently working on a project in which I load a huge number of data points on a graph (something like 50,000, so I can zoom in as much as I want).
I wanted to test how the commands worked, so I thought I'd try out the code with 10 pieces of data, but unfortunately my curve refuses to show up on my graph.
QwtPlot *leftGraph;
leftGraph = new QwtPlot;
leftGraph->setCanvasBackground(Qt::white);
leftGraph->setMaximumHeight(200);
leftGraph->setAxisScale(0, 0.0, 20.0, 2.0);
leftGraph->setAxisScale(2, 0.0, 20.0, 2.0);
and
QwtPlotCurve *curve = new QwtPlotCurve();
curve->setStyle(QwtPlotCurve::Lines);
curve->setCurveAttribute(QwtPlotCurve::Fitted, true);
const double x[] = {0, 1, 2, 4, 5, 8, 10, 13, 14, 19};
const double y[] = {17, 16.5, 8, 3, 5, 7.5, 9, 10, 12, 14};
curve->setSamples(x, y, 10);
curve->attach(leftGraph);
Any ideas? Many thanks.
Try calling leftGraph->replot() to make the curve appear.