C++: Boost interprocess memory mapped file error - c++

I'm trying to create a memory mapped file using this answer, but I'm getting compile errors. This is my code:
namespace bi = boost::interprocess;
std::string vecFile = "vector.dat";
bi::managed_mapped_file file_vec(bi::open_or_create,vecFile.c_str(), sizeof(struct Rectangle) * data_size);
typedef bi::allocator<struct Rectangle, bi::managed_mapped_file::segment_manager> rect_alloc;
typedef std::vector<struct Rectangle, rect_alloc> MyVec;
MyVec * vecptr = file_vec.find_or_construct<MyVec>("myvector")(file_vec.get_segment_manager());
vecptr->push_back(random_rectangle);
The struct is this:
struct Rectangle{
Rectangle(float *minArr, float *maxArr, int arr, int exp, int ID){
this->arrival = arr;
this->expiry = exp;
this->id = ID;
for(int i=0; i < 2; i++){
min[i] = minArr[i];
max[i] = maxArr[i];
}
int arrival, expiry, id;
float min[2];
float max[2];
}
The error I get is: Compiler could not deduce the template argument for '_Ty*' from 'boost::interprocess::offset_ptr'. What am I doing wrong?

It looks okay to me:
Live On Coliru
#include <boost/interprocess/managed_mapped_file.hpp>
#include <vector>
namespace bi = boost::interprocess;
struct Rectangle {
Rectangle(float *minArr, float *maxArr, int arr, int exp, int ID) {
this->arrival = arr;
this->expiry = exp;
this->id = ID;
for (int i = 0; i < 2; i++) {
min[i] = minArr[i];
max[i] = maxArr[i];
}
};
int arrival, expiry, id;
float min[2];
float max[2];
};
namespace Shared {
using segment = bi::managed_mapped_file;
using mgr = segment::segment_manager;
using alloc = bi::allocator<Rectangle, mgr>;
using vector = std::vector<Rectangle, alloc>;
}
Rectangle random_rectangle() {
float dummy[2] = { };
return { dummy, dummy, 0, 0, 0 };
}
int main() {
#define data_size 10
std::string vecFile = "vector.dat";
Shared::segment mmem(bi::open_or_create, vecFile.c_str(), (10u<<10) + sizeof(struct Rectangle) * data_size);
Shared::vector *vecptr = mmem.find_or_construct<Shared::vector>("myvector")(mmem.get_segment_manager());
vecptr->push_back(random_rectangle());
}
If it doesn't compile exactly as above, please note versions of your library and compiler. Consider upgrading.

Related

Having trouble reading a struct with a vector<string> from a binary file

I'm making my OOP final project and part of it is to make a couple of databases, I'm having trouble with this one.
Every time an Alquiler x is made, it needs to go to the database's vector<Alquiler>, and then stored in a binary file. Problem is that I'm probably managing the sizes wrong because once I add a couple of Alquiler, the array gets filled up with rubbish, always outputting random characters.
Here's the code, I tried to compact it as much as possible and just leave the relevant part. If anyone wants to take a look I'd really appreciate it.
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
struct Date
{
int day, month, year;
};
struct structalquiler
{
int dni, totalq, dep;
int faday, famonth, fayear;
int fdday, fdmonth, fdyear;
vector<string> artlist;
};
class Alquiler {
private:
int a_DNI_Cliente;
int a_Total_Alquiler, a_Deposito;
Date a_Date_Alquiler, a_Date_Devolucion;
vector<string> a_Article_list;
public:
Alquiler ();
Alquiler (int dni, int totalq, int dep, Date fa, Date fd, vector<string> arts);
void save(ofstream &outfile) { // Bin file writing
structalquiler reg;
reg.dni = a_DNI_Cliente;
reg.dep = a_Deposito;
reg.totalq = a_Total_Alquiler;
reg.faday = a_Date_Alquiler.day;
reg.famonth = a_Date_Alquiler.month;
reg.fayear = a_Date_Alquiler.year;
reg.fdday = a_Date_Devolucion.day;
reg.fdmonth = a_Date_Devolucion.month;
reg.fdyear = a_Date_Devolucion.year;
reg.artlist = a_Article_list;
int wo_size = sizeof(reg) - sizeof(reg.artlist);
outfile.write((char*)&reg, wo_size);
int size = reg.artlist.size(); // Writing of the vector<string>
outfile.write((char*)&size, sizeof(int));
for (int i = 0; i < size; i++)
{
int letter_amount = reg.artlist[i].length();
outfile.write((char*)&letter_amount, sizeof(int));
outfile.write(reg.artlist[i].c_str(), letter_amount);
}
}
void read(ifstream &infile) { // Reading of the file
structalquiler reg;
int wo_size = sizeof(reg) - sizeof(reg.artlist);
infile.read((char*)&reg, wo_size);
a_DNI_Cliente = reg.dni;
a_Deposito = reg.dep;
a_Total_Alquiler = reg.totalq;
a_Date_Alquiler.day = reg.faday;
a_Date_Alquiler.month = reg.famonth;
a_Date_Alquiler.year = reg.fayear;
a_Date_Devolucion.day = reg.fdday;
a_Date_Devolucion.month = reg.fdmonth;
a_Date_Devolucion.year = reg.fdyear;
// a_Article_list = reg.artlist;
vector<string> v; // Reading of the vector<string>
int read_size;
infile.read((char*)&read_size, sizeof(int));
for (int i = 0; i < read_size; i++)
{
int letter_amount;
infile.read((char*)&letter_amount, sizeof(int));
char* buffer = new char[letter_amount + 1];
infile.read(buffer, letter_amount);
buffer[letter_amount] = '\0';
v.push_back(string(buffer));
delete [] buffer;
}
a_Article_list = v;
}
};
Alquiler::Alquiler(){}
Alquiler::Alquiler(int dni, int totalq, int dep, Date fa, Date fd, vector<string> arts)
: a_DNI_Cliente(dni), a_Total_Alquiler(totalq), a_Deposito(dep), a_Date_Alquiler(fa), a_Date_Devolucion(fd), a_Article_list(arts) {}
class Database {
private:
string m_file_name = "alquileres.dat";
vector<Alquiler> Arreglo_Alquileres;
public:
Database() { // storing in the vector<Alquiler>
ifstream infile(m_file_name.c_str(), ios::binary|ios::ate);
if (infile.is_open())
{
int size = infile.tellg();
int cant = size / sizeof(structalquiler);
Arreglo_Alquileres.resize(cant);
infile.seekg(0);
for (int i = 0; i < cant; i++)
{
Arreglo_Alquileres[i].read(infile);
}
infile.close();
}
}
void add(const Alquiler &x) {
Arreglo_Alquileres.push_back(x);
write();
}
bool write() {
ofstream outfile(m_file_name.c_str(), ios::binary|ios::trunc);
if (!outfile.is_open()) return false;
int cant = Arreglo_Alquileres.size();
for (int i = 0; i < cant; i++)
{
Arreglo_Alquileres[i].save(outfile);
}
outfile.close();
return true;
}
};
int main() {
Database base;
vector<string> v = {"panuelo", "alpargatas", "chaleco"};
Alquiler x(9,8,7,{6,5,4},{3,2,1},v);
base.add(x);
return 0;
}
Any help is appreciated.
I used a debugger to check your code as is step by step. And then I used a hex-editor to show the output.
And the result is: Your code, as shown, works fine.
But, if you use longer strings, then the std::vector in the structalquiler will have a variable length.
If you now want to read back the data, then you cannot calculate the number of elements from the filesize.
Example for Hex file after running the program as shown one time:
You can see that there is a padding of one int after the 9 data ints. But assuming that the program runs in the same environment, there should be no problem.
And this codes works fine. So, running the program 3 times it will give:
But now: What if we have longer string, then, we could get a file like this:
So, int cant = size / sizeof(structalquiler); will not work any longer.
The solution is to read the file, record for record, until all data from the file will be consumed.
I will show you a quick fix, but you should consider a redesign.
The following will work:
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
struct Date
{
int day, month, year;
};
struct structalquiler
{
int dni, totalq, dep;
int faday, famonth, fayear;
int fdday, fdmonth, fdyear;
vector<string> artlist;
};
class Alquiler {
private:
int a_DNI_Cliente;
int a_Total_Alquiler, a_Deposito;
Date a_Date_Alquiler, a_Date_Devolucion;
vector<string> a_Article_list;
public:
Alquiler();
Alquiler(int dni, int totalq, int dep, Date fa, Date fd, vector<string> arts);
void save(ofstream& outfile) { // Bin file writing
structalquiler reg;
reg.dni = a_DNI_Cliente;
reg.dep = a_Deposito;
reg.totalq = a_Total_Alquiler;
reg.faday = a_Date_Alquiler.day;
reg.famonth = a_Date_Alquiler.month;
reg.fayear = a_Date_Alquiler.year;
reg.fdday = a_Date_Devolucion.day;
reg.fdmonth = a_Date_Devolucion.month;
reg.fdyear = a_Date_Devolucion.year;
reg.artlist = a_Article_list;
int sss1 = sizeof(reg);
int sss2 = sizeof(reg.artlist);
int wo_size = sizeof(reg) - sizeof(reg.artlist);
outfile.write((char*)&reg, wo_size);
int size = reg.artlist.size(); // Writing of the vector<string>
outfile.write((char*)&size, sizeof(int));
for (int i = 0; i < size; i++)
{
int letter_amount = reg.artlist[i].length();
outfile.write((char*)&letter_amount, sizeof(int));
outfile.write(reg.artlist[i].c_str(), letter_amount);
}
}
void read(ifstream& infile) { // Reading of the file
structalquiler reg;
int wo_size = sizeof(reg) - sizeof(reg.artlist);
if (infile.read((char*)&reg, wo_size)) {
a_DNI_Cliente = reg.dni;
a_Deposito = reg.dep;
a_Total_Alquiler = reg.totalq;
a_Date_Alquiler.day = reg.faday;
a_Date_Alquiler.month = reg.famonth;
a_Date_Alquiler.year = reg.fayear;
a_Date_Devolucion.day = reg.fdday;
a_Date_Devolucion.month = reg.fdmonth;
a_Date_Devolucion.year = reg.fdyear;
// a_Article_list = reg.artlist;
vector<string> v; // Reading of the vector<string>
int read_size;
infile.read((char*)&read_size, sizeof(int));
for (int i = 0; i < read_size; i++)
{
int letter_amount;
infile.read((char*)&letter_amount, sizeof(int));
char* buffer = new char[letter_amount + 1];
infile.read(buffer, letter_amount);
buffer[letter_amount] = '\0';
v.push_back(string(buffer));
delete[] buffer;
}
a_Article_list = v;
}
}
};
Alquiler::Alquiler() {}
Alquiler::Alquiler(int dni, int totalq, int dep, Date fa, Date fd, vector<string> arts)
: a_DNI_Cliente(dni), a_Total_Alquiler(totalq), a_Deposito(dep), a_Date_Alquiler(fa), a_Date_Devolucion(fd), a_Article_list(arts) {}
class Database {
private:
string m_file_name = "r:\\alquileres.dat";
vector<Alquiler> Arreglo_Alquileres;
public:
Database() { // storing in the vector<Alquiler>
ifstream infile(m_file_name.c_str(), ios::binary | ios::ate);
if (infile.is_open())
{
int size = infile.tellg();
int ss2 = sizeof(structalquiler);
int cant = size / sizeof(structalquiler);
//Arreglo_Alquileres.resize(cant);
infile.seekg(0);
while (infile) {
Arreglo_Alquileres.push_back({});
Arreglo_Alquileres.back().read(infile);
}
if (not infile) Arreglo_Alquileres.pop_back();
infile.close();
}
}
void add(const Alquiler& x) {
Arreglo_Alquileres.push_back(x);
write();
}
bool write() {
ofstream outfile(m_file_name.c_str(), ios::binary | ios::trunc);
if (!outfile.is_open()) return false;
int cant = Arreglo_Alquileres.size();
for (int i = 0; i < cant; i++)
{
Arreglo_Alquileres[i].save(outfile);
}
outfile.close();
return true;
}
};
int main() {
Database base;
vector<string> v = { "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", "alpargatas", "chaleco" };
Alquiler x(9, 8, 7, { 6,5,4 }, { 3,2,1 }, v);
base.add(x);
return 0;
}

#ifndef error : need to update includepath

My header file "broker.h" is
#ifndef _BROKER_
#define _BROKER_
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <list>
#include <iterator>
#include <vector>
#include "strategy.h"
#include "utils.h"
using namespace std;
class Broker{
private:
vector< vector<double> > buy_signals; //time X codes
vector< vector<double> > sell_signals; //time X codes
vector< vector<double> > positions; //time X codes
vector< vector<double> > cashs; //time X 1
vector< vector<double> > prices; // time X codes
vector<double> position;
fstream fs;
fstream indi;
vector<string>codes;
vector<string>time_index;
int n_cols, n_rows;
double return_mean, sharp;
Strategy strategy;
public:
double cash;
double unit;
template<typename T>
void set_data(vector<string>& _codes, const map<string, vector<T>>>& _fs, const map<string, vector<T>>>& _indi, const vector<vector<double>>& _prices, const vector<string>& _time_index){
codes = _codes;
time_index = _time_index; //2015-2020
n_cols = codes.size();
n_rows = time_index.size();
/*
I don't know which data type is better for multi-index columns
fs=_fs;
indi = _indi;
*/
buy_signals = zero_vector(buy_signals, n_rows, n_cols);
sell_signals = zero_vector(sell_signals, n_rows, n_cols);
positions = zero_vector(positions, n_rows, n_cols);
cashs = zero_vector(cashs, n_rows, 1);
prices = _prices;
vector<vector<double>> temp;
position = zero_vector(temp, 1, n_cols)[0];
};
void update_data(Strategy s, int date_index){
cash = s.cash;
position = s.position;
cashs[i] = s.cash; // times X 1 : vector< vector<int> >
positions[i] = s.position; // times X codes : vector<vector<int>>
buy_signals[i] = s.buy_signal;
sell_signals[i] = s.sell_signal;
};
void run(){
for (int i=0; i < n_rows ; i++) {
string date = time_index[i];
string year = date.substr(0,4);
string prev_year = to_string(stoi(year)-1);
// 추상적 데이터 접근 - fs 데이터 타입 정해진 후 수정 바람
prev_fs_row = fs[prev_year]; // Not exact fs data type
curr_fs_row = fs[year];
curr_indi_row = indi[date];
Strategy strat = Strategy();
strat.set_data(prev_fs_row, curr_fs_row, curr_indi_row, codes, unit, cash);
strat.run();
update_data(strat, i);
}
};
void performance(){
vector<double> last_price = prices.back(); // {vector<int>, vector<int>, ....}
vector<double> total_remain_num = position;
vector<vector<double>> total_buy_data = d2_vec_mul(prices, buy_signals);
vector<vector<double>> total_sell_data = d2_vec_mul(prices, sell_signals);
double total_buy = sum_vector(sum_vector(total_buy_data, 1))[0][0];
double total_sell = sum_vector(sum_vector(total_sell_data, 1))[0][0];
double total_remain = vec_mul(last_price, total_remain_num)[0];
double profit = total_sell + total_remain - total_buy;
if (total_buy) {
return_mean = profit/total_buy;
}
else{
cout << "No buy!" <<endl;
return;
}
int n_rows = time_index.size();
// prices : already change from na -> 0 (from python)
vector<vector<double>> posses_stock_value = sum_vector(d2_vec_mul(positions, prices), 1); // times X 1
vector<vector<double>> accumulates = sum_vectors(cashs, posses_stock_value);
vector<vector<double>> shift_accumulates = shift_vector(accumulates);
vector<vector<double>> daily_return = divide_vectors(sum_vectors(accumulates, shift_accumulates, 0), shift_accumulates);
vector<double> temp ={1}; vector<vector<double>> ones(n_rows, temp);
daily_return = sum_vectors(daily_return, ones, 0);
temp.clear();
temp.push_back(return_mean); vector<vector<double>> daily_return_mean(n_rows, temp);
vector<vector<double>> daily_Err = (sum_vectors(pop_front(daily_return), pop_front(daily_return_mean));
double SSE = sum_vector(d2_vec_mul(daily_Err, daily_Err));
double std = power_vector(SSE, 0.5);
sharp = return_mean / std;
}
};
#endif
And there is an error in #ifndef BROKER as "There is #include error. Please update includePath."
My c_cpp_properties.json is
My project folder location is
However, my includepath is correct and when I just a simple HelloWorld.cpp there is no error. Why is there an error in #ifndef??

Initialize and declare dynamically multiple variables of random entities in a loop in C++

This is my code:
#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <vector>
#define ENTITY(A) entity##A
#define ALM(A) alm##A
struct TEntity{
private:
int sumx;
int sumy;
const char * rep;
int m_ix;
int m_iy;
public:
TEntity(int x, int y, int sum_x, int sum_y, const char * txt);
};
TEntity::TEntity(int x, int y, int sum_x, int sum_y, const char * txt) {
m_ix = x;
m_iy = y;
sumx = sum_x;
sumy = sum_y;
rep = txt;
}
class IAlmacenable {
private:
void * element;
public:
IAlmacenable(void * e);
IAlmacenable();
void * getValue();
};
IAlmacenable::IAlmacenable(void *e) {
element = e;
}
IAlmacenable::IAlmacenable() {
element = nullptr;
}
void * IAlmacenable::getValue() {
return element;
}
class TList {
private:
std::vector<IAlmacenable*> elementos;
int position;
public:
TList();
int Size();
int Push(IAlmacenable* psz);
};
TList::TList() {
elementos = std::vector<IAlmacenable*>();
position = 0;
}
int TList::Size() {
return elementos.size();
}
int TList::Push(IAlmacenable* psz) {
int res = 0;
if (elementos.size() >= elementos.max_size()) {
res = -1;
}
else {
elementos.push_back(psz);
}
return res;
}
int main(){
srand(time(NULL));
TList *list = new TList();
//we can put entities in the list and the rest will be filled up to 5
int size = list->Size();
for(int i = size; i<5;i++){
const char c[] = {(rand() % 2 ? 65 + rand() % 25 : 97 + rand() % 25), '\0'};
TEntity ENTITY(i)(rand() % 10, rand() % 10, rand() % 5, rand() % 5, c);
IAlmacenable ALM(i)(&ENTITY(i));
list->Push(&ALM(i));
size++;
}
//do things like printing their value...
delete list;
return 0;
}
I need to create a new variable everytime it run the "TEntity ENTITY(i)" line,
the problem is that it creates the same variable always, I think it is because it creates the variable entityi and therefore it is overwriting on the same variable, besides it seems that the random it generates is always the same number since all entities have the same values ​​in all its parameters. The c variable create a const char * random variable between a-z, A-Z , I don't put the print code because it is unnecessary, so what can I do? Is there any way to dynamically create variables of entities whose values ​​are random?
EDIT
Here is the new code fixed (the macros have been eliminated since they were not necessary and the necessary code has been included to be able to execute it) but there is still the same problem that they are generated with the same parameters (since they are still the same variable):
#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <vector>
#include <conio.h>
#include <windows.h>
struct TEntity{
private:
int sumx;
int sumy;
const char * rep;
int m_ix;
int m_iy;
public:
TEntity(int x, int y, int sum_x, int sum_y, const char * txt);
void movimiento();
void pinta();
};
TEntity::TEntity(int x, int y, int sum_x, int sum_y, const char * txt) {
m_ix = x;
m_iy = y;
sumx = sum_x;
sumy = sum_y;
rep = txt;
}
void TEntity::movimiento() {
m_ix += sumx;
m_iy += sumy;
}
void TEntity::pinta() {
gotoxy(static_cast<short int>(m_ix), static_cast<short int>(m_iy));
printf("%s", rep);
}
void gotoxy(short int x, short int y)
{
COORD pos = {x, y};
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}
void clear()
{
system("cls");
}
class IAlmacenable {
private:
void * element;
public:
IAlmacenable(void * e);
IAlmacenable();
void * getValue();
};
IAlmacenable::IAlmacenable(void *e) {
element = e;
}
IAlmacenable::IAlmacenable() {
element = nullptr;
}
void * IAlmacenable::getValue() {
return element;
}
class TList {
private:
std::vector<IAlmacenable*> elementos;
int position;
public:
TList();
int Size();
int Push(IAlmacenable* psz);
IAlmacenable* First();
IAlmacenable* Next();
};
TList::TList() {
elementos = std::vector<IAlmacenable*>();
position = 0;
}
int TList::Size() {
return elementos.size();
}
int TList::Push(IAlmacenable* psz) {
int res = 0;
if (elementos.size() >= elementos.max_size()) {
res = -1;
}
else {
elementos.push_back(psz);
}
return res;
}
IAlmacenable* TList::First() {
IAlmacenable* res;
if (elementos.empty()) {
res = nullptr;
}
else {
res = elementos.front();
position = 1;
}
return res;
}
IAlmacenable* TList::Next() {
IAlmacenable* res;
if (elementos.empty()) {
res = nullptr;
}
else {
int pos = position;
int size = elementos.size();
if (pos < size) {
res = elementos.at(position);
position++;
}
else {
res = this->First();
}
}
return res;
}
int main(){
srand(time(NULL));
TList *list = new TList();
//we can put entities in the list and the rest will be filled up to 5
int size = list->Size();
for(int i = size; i<5;i++){
const char c[] = {(rand() % 2 ? 65 + rand() % 25 : 97 + rand() % 25), '\0'};
TEntity *entity = new TEntity(rand() % 10, rand() % 10, rand() % 5, rand() % 5, c);
IAlmacenable *alm = new IAlmacenable(entity);
list->Push(alm);
size++;
}
while(true){
clear();
for (int i = 0; i < size; i++) {
reinterpret_cast<TEntity *>(list->Next()->getValue())->pinta();
reinterpret_cast<TEntity *>(list->Next()->getValue())->movimiento();
}
Sleep(2000);
}
delete list;
return 0;
}
There is some confusion here.
Some points:
The macro is not fit-for-purpose, as you already know; you're just creating a variable name entityi each time;
That doesn't matter! The object only exists for the duration of the loop iteration anyway; C++ doesn't let you create multiple objects with the same name at the same time. In fact you can get rid of the entire macro stuff and just call the object entity;
Now that that's out of the way, you're getting repeated results because you're storing a pointer to each iteration of that local variable — on each occasion, that's a dangling pointer to an object that's been destroyed. Don't store dangling pointers!
You can either:
Dynamically allocate the objects that you're adding to the list, or
Store actual objects rather than pointers-to-objects.
Either way, the local-scope name is irrelevant and certainly need not change repeatedly for each loop iteration.

Creating multiple instances of c++ library

I am trying to create multiple instances of a static c++ library I wrote, but I can't create multiple instances of it... When I create two instances and write different data to them, I read the same data from both of the instances. Here is my code:
.cpp file:
// MathFuncsLib.cpp
// compile with: cl /c /EHsc MathFuncsLib.cpp
// post-build command: lib MathFuncsLib.obj
/*
DECLARING VECTORS
|3,6,4|
|9,1,5|
|2,0,2|
|5,3,6|
Should be inputted as:
int a[] = {3,6,4,9,1,5,2,0,2,5,3,6} with x = 3 and y = 4
Inputting training vals:
|0.1 (inp1),0.1 (inp2) ,0.1 (targeted output)| depends on the number of inputs and outputs
|9,1,5|
|2,0,2|
|5,3,6|
*/
//#include "stdafx.h"
#include "vector.h"
#include "iostream"
#define DEBUG
#include <stdexcept>
//using namespace std;
double* vectorLib::arrayPtr;
int vectorLib::x;
int vectorLib::y;
vectorLib::vectorLib(int xInp, int yInp) {
vectorLib::arrayPtr = new double[xInp*yInp];
vectorLib::x = xInp;
vectorLib::y = yInp;
//return 0;
}
double vectorLib::sigmoid(double inp) {
return 1 / (1 + exp(-inp));
}
double* vectorLib::getArrayPtr() {
return vectorLib::arrayPtr;
}
double vectorLib::read(int xInp, int yInp) {
#ifdef DEBUG
if (xInp >= vectorLib::x) {
std::cout << "X_OUT_OF_BOUNDS_VECTOR_READ\n";
while (1);
}
if (yInp >= vectorLib::y) {
std::cout << "X_OUT_OF_BOUNDS_VECTOR_READ\n";
while (1);
}
#endif // DEBUG
return *(arrayPtr + xInp + vectorLib::x*yInp);
}
void vectorLib::write(int xInp, int yInp, double data) {
#ifdef DEBUG
if (xInp >= vectorLib::x) {
std::cout << "X_OUT_OF_BOUNDS_VECTOR_WRITE\n";
while (1);
}
if (yInp >= vectorLib::y) {
std::cout << "X_OUT_OF_BOUNDS_VECTOR_WRITE\n";
while (1);
}
#endif // DEBUG
vectorLib::arrayPtr[xInp + vectorLib::x*yInp] = data;
}
void vectorLib::writeArr(double* inpArr) {
int i;
for (i = 0; i < vectorLib::x*vectorLib::y; i++) {
vectorLib::arrayPtr[i] = *(inpArr + i);
}
}
void vectorLib::sigmoidVect() {
int yy;
int xx;
for (yy = 0; yy < vectorLib::y; yy++) {
for (xx = 0; xx < vectorLib::x; xx++) {
write(xx, yy, sigmoid(read(xx, yy)));
}
}
write(0, vectorLib::y - 1, 1);
}
int vectorLib::getX() {
return vectorLib::x;
}
int vectorLib::getY() {
return vectorLib::y;
}
int vectorLib::totalVectSize() {
return vectorLib::x * vectorLib::y;
}
void vectorLib::printVector() {
int yy;
int xx;
for (yy = 0; yy < y; yy++) {
for (xx = 0; xx < x; xx++) {
std::cout << vectorLib::read(xx, yy);
if (xx + 1 != x) {
std::cout << ",";
}
}
std::cout << "\n";
}
}
vectorLib* vectorLib::vectorMult(vectorLib* vect1, vectorLib* vect2) {
#ifdef DEBUG
if (vect1->getX() != vect2->getY()) {
std::cout << "INPUTS_DONT_MATCH_VECTORMULT\n";
while (1);
}
#endif // DEBUG
vectorLib toRet(vect1->getX(), vect2->getY());
int i;
for (i = 0; i < vect2->getX(); i++) {
int p;
for (p = 0; p < vect1->getY(); p++) {
double tempOut = 0;
int q;
for (q = 0; q < vect1->getX(); q++)
{
tempOut += vect1->read(q, p) * vect2->read(i, q);
}
toRet.write(i, p, tempOut);
}
}
return &toRet;
}
.h file:
//#include "stdafx.h"
using namespace std;
class vectorLib
{
//int x, y;
public:
static double* arrayPtr;
static int x;
static int y;
//Constructor takes x and y of the vector
vectorLib(int xInp, int yInp);
//The pointer to the array that holds all the doubles in the vector
static double* getArrayPtr();
//Read the vector at a specified x and y
static double read(int xInp, int yInp);
//Write one double to a specific location
static void write(int xInp, int yInp, double data);
//Write the array inside the vector class
static void writeArr(double* inpArr);
//Takes sigmoid of whole vector
static void sigmoidVect();
//Returns x of vector
static int getX();
//Returns y of vector
static int getY();
//Returns total size of vector
static int totalVectSize();
//Returns a vector pointer to the multiplication result
static vectorLib* vectorMult(vectorLib* vect1, vectorLib* vect2);
//Prints vector
static void printVector();
private:
static double sigmoid(double inp);
};
Main file:
#define DEBUG
#include "stdafx.h"
#include "vector.h"
#include "iostream"
using namespace std;
int main()
{
vectorLib testVectLol(1, 3);
vectorLib testVect(3, 4);
double vectInp[] = { 1,1,1,
1,1,1,
1,1,1,
1,1,1};
double vectInp2[] = { 0.5,0.5,0.5 };
testVect.writeArr(vectInp);
testVectLol.writeArr(vectInp2);
testVect.printVector();// Both print 0.5, 0.5, 0,5
testVectLol.printVector();// Both print 0.5, 0.5, 0,5
while (1);
return 0;
}
Thanks in advance! I've been struggling with this for hours. I would really appreciate any help!
Jasper

Vector::push_back not storing values in vector

Recently I've been trying to write a neural network program. I have all a neurons connections stored in a vector in the neuron. However whenever I push back a connection into the vector it doesn't seem to store (I can tell via debug mode), and when I try to add up the activation values of the vectors in a for loop, I get an out_of_range error. Here's my code.
Main.cpp
#include <iostream>
#include "neuron.h"
void displayboard(bool board [8][8]);
using namespace std;
int main()
{
int id = 2;
int inputids [] = {3};
int outputids [] = {4};
int inputweights [] = {5};
bool new_neuron = true;
neuron test (inputids, outputids, inputweights, new_neuron, id);
test.connections.at(0).value = 6;
// here is where the error is returned
test.activation();
cout << test.activationnumber;
return 0;
}
And here's Neuron.cpp:
#include "neuron.h"
#include <vector>
#include <random>
#include <ctime>
using namespace std;
neuron::neuron(int inputids [], int outputids [], int inputweights [],
bool new_neuron, int id)
{
this->id = id;
if (new_neuron==true) {
srand (time(0));
connection tempconnection;
for (int i = 0; i <=(sizeof (inputids)/sizeof (inputids [0])); i++)
{
tempconnection.type=false;
tempconnection.tofrom = inputids [i];
tempconnection.weight = rand ();
this->connections.push_back (tempconnection);
}
// this continues on for other options
}
void neuron::activation (){
for (int i=0; i<=this->connections.size (); i++) {
this->activationnumber += ((this->connections.at(i).value)
*(this->connections.at (i).weight));
}
}
UPDATE: Reading this will help you understand why your "sizeof/sizeof" approach is not good in C++.
Original answer
The behavior of sizeof(array)/sizeof(array[0]) might not be what you expected. The following code outputs 2 but you seem to expect 4. Use array for objects in the stack or vector for objects in the heap.
#include <iostream>
using namespace std;
void foo( int array[] )
{
wcout << sizeof( array ) / sizeof( array[ 0 ] );
}
int main()
{
int test[ 4 ];
foo( test );
return 0;
}
Change
int inputids [] = {3};
int outputids [] = {4};
to
vector< int > {3};
vector< int > {4};
Also change
neuron(int inputids [],int outputids [] …
{
…
for (int i = 0; i <= …; i++)
…
tempconnection.tofrom = inputids [i];
to
neuron( vector< int > & inputids, vector< int > & outputids …
{
…
for( auto id : inputids )
…
tempconnection.tofrom = id;