Here I'm trying to mimic data feed streaming from stock exchange using random number and subsequently store it in array.
#include <iostream>
#include <array>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <chrono>
#include <ctime>
#include <stdlib.h>
long int prevcntr=0;
using namespace std;
std::pair<long int, double>feedgenerator(long int len)
{
srand(time(0));
for(long int itr=1;itr<=len;itr++)
{
return {itr, (double)rand()/RAND_MAX};
//should continue evaluating the function without exiting
pause(0.001); //To allow some interval for 'makearray' to store it
}
}
template<size_t nn>
std::array<double, nn> makearray(long int cntr, double value, long int len)
{
std::array<double, nn> outarr; // should be able to pass the value of 'len' to 'nn'
long int itr=0;
begin:
while(cntr <= prevcntr)goto begin; // should wait until the next update
outarr[itr] = value;
prevcntr = cntr;
while(itr<len)
{
itr++;
goto begin; // control goes back to the beginning until all the elements of the array are filled with value
}
//should return the array after it is fully filled
return outarr;
}
int main()
{
double *p=new double[];
long int len = 100000;
*p = makearray(feedgenerator(len), len)
// I should be able to call these as nested functions as above
for(int i=0;i<len;i++)
cout<<*p[i]<<"\n";
return 0;
}
Question is how do I return a value without exiting the feedgenerator function. If I try to get all the values at once then it wouldn't mimic the data feed. Data feed is essentially, the same value being updated, sequentially.
To store the data, makearray is being used (vector shouldn't be used as it is extremely slow).
Overall the idea is, feedgenerator should update the same value with an increasing counter (in the real scenario counter will be the time and value will be price etc.) and makearray should store the data (Unless I store the data, the data would be lost, as in the case of data feed from stock exchange) for subsequent analysis.
In makearray, I want to pass the length of the array as an argument of the function, so that it can be controlled by another program. How can it be done is not clear to me.
The code in it's present form, doesn't compile.
Question is how do I return a value without exiting the feedgenerator function
Because you are trying to mimic the data feed stream from stock exchange, so, I think you should consider to use thread. Example:
#include <unistd.h>
#include <deque>
#include <vector>
#include <algorithm>
#include <mutex>
#include <thread>
#include <iostream>
class FeedGenerator {
long int max_length;
std::deque<double> queue;
std::mutex mutex;
std::thread thread;
bool stop;
public:
FeedGenerator(long int len) :
max_length(len), stop(false),
thread(&FeedGenerator::run, this) {
}
virtual ~FeedGenerator() {
stop = true;
thread.join();
}
// Get the latest `len` values
int getData(std::vector<double>& vec, int len) {
std::lock_guard<std::mutex> lock(mutex);
if (queue.empty()) return 0;
int nlen = std::min((size_t)len, queue.size());
vec.resize(nlen);
std::copy(queue.end() - nlen, queue.end(), vec.begin());
return nlen;
}
private:
void run() {
srand(time(0));
while (!stop)
{
{
std::lock_guard<std::mutex> lock(mutex);
queue.push_back((double)rand()/RAND_MAX);
if (queue.size() >= max_length) {
queue.pop_front();
}
}
usleep(1000);
}
}
};
int main()
{
long int len = 100000;
FeedGenerator feedgenerator(len);
sleep(1);
std::vector<double> p;
feedgenerator.getData(p, 10); // get the latest 10 values
for(int i=0;i<p.size();i++)
std::cout << p[i] << std::endl;
return 0;
}
I am trying to use __malloc_hook in our code to manage memory. But It is impacting to client code as well where I don't want to manage memory.
Below is the sample code. :
mathtest.h
int addNumbers(int x, int y);
int subNumbers(int x, int y);
addNumbers.cpp
#include <cstdlib>
#include <iostream>
#include <malloc.h>
using namespace std;
static void my_init_hook (void);
static void *my_malloc_hook (size_t, const void *);
//static void my_free_hook (void*, const void *);
/* Variables to save original hooks */
static void *(*old_malloc_hook)(size_t, const void *);
static void
my_init_hook (void)
{
old_malloc_hook = __malloc_hook;
//old_free_hook = __free_hook;
__malloc_hook = my_malloc_hook;
//__free_hook = my_free_hook;
}
static void *
my_malloc_hook (size_t size, const void *caller)
{
void *result;
/* Restore all old hooks */
__malloc_hook = old_malloc_hook;
// __free_hook = old_free_hook;
/* Call recursively */
result = malloc (size);
/* Save underlying hooks */
old_malloc_hook = __malloc_hook;
//old_free_hook = __free_hook;
/* printf might call malloc, so protect it too. */
printf ("malloc (%u) returns %p\n", (unsigned int) size, result);
/* Restore our own hooks */
__malloc_hook = my_malloc_hook;
//__free_hook = my_free_hook;
return result;
}
int addNumbers(int x, int y)
{
my_init_hook();
int *p = (int*)malloc (100);
cout<<"memory in add numbers : "<<p<<endl;
return x+y;
}
subNumbers.cpp
#include <iostream>
#include <malloc.h>
#include <cstdlib>
using namespace std;
int subNumbers(int x, int y)
{
int *p = (int*)malloc (100);
cout<<"memory in sub numbers : "<<p<<endl;
return x-y;
}
doMath.cpp (Client code)
#include <time.h>
#include <iostream>
#include <cstdlib>
#include "mathtest.h"
using namespace std;
int main()
{
time_t t;
srand((unsigned) time(&t));
int rNuma = rand();
int rNumb = rand();
int answer;
answer = addNumbers(rNuma, rNumb);
cout<<"add = "<<answer<<endl;
answer = subNumbers(rNuma, rNumb);
cout<<"Subtract = "<<answer<<endl;
int *p = (int*)malloc(20000);
cout<<"malloc address in domath : "<<p;
return 0;
}
Header are inside include folder and SO will be kept inside lib folder.
Below are the steps to compile.
g++ -fpic -c addNumbers.cpp subNumbers.cpp
g++ -o libmath.so.1.3.0 addNumbers.o subNumbers.o -fpic -shared -Wl,-soname,libMath.so.1
create soft link
g++ doMath.cpp -o doMath -lMath -I include -L lib
./doMath
Below is the output:
malloc (100) returns 0x564b23f6ee70
memory in add numbers : 0x564b23f6ee70
add = 1549862266
malloc (100) returns 0x564b23f6f2f0
memory in sub numbers : 0x564b23f6f2f0
Subtract = 1535975764
malloc (20000) returns 0x564b23f6f360
__malloc_hook callback is getting called for client code as well. which I don't want.
One possible solution is to reset __malloc_hook callback before calling malloc in client code. But this solution would not work if client code is running on separate thread.
Any possible solution where We can restrict the __malloc_hook so that It doesn't affect the client code. Any help would be much appreciated. Thanks in Advance.
Here is the whole code.
I know that the problem is somewhere in the hozzaad function, but I don't know to debug it.
I want to create a dynamic 2d array, with exacly vagonszam columns, but the number of rows differ.
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdlib>
using namespace std;
class Vonat{
int vagonszam, maxtomb;
int **vagonok;
int *seged;
enum szallitmany {szen, fa, ko} ;
public:
void beolvas(int x);
Vonat(): vagonszam(0), maxtomb(0) {}
void kiir();
void hozzaad(int **vagonok, int i, string szallitmany);
};
void Vonat::hozzaad(int **vagonok, int i, string szallitmany)
{
++vagonok[i][0];
seged = (int *) realloc(vagonok[i], ((vagonok[i][0]+1)*sizeof(int)));
seged[vagonok[i][0]]=1;
}
void Vonat::beolvas(int x)
{
char szovegesallomany[]="beVagonTartalma";
szovegesallomany[15]=x+'0';
szovegesallomany[16]='\0';
strcat(szovegesallomany, ".txt");
ifstream f(szovegesallomany);
f>>vagonszam>>maxtomb;
vagonok = new int*[vagonszam];
string szallitmany;
for(int i=0;i<vagonszam;i++)
{
vagonok[i] = new int[1];
vagonok[i][0]=0;
do
{
f>>szallitmany;
cout<<szallitmany<<" ";
hozzaad(vagonok, i, szallitmany);
}
while(szallitmany!="*");
}
f.close();
}
void Vonat::kiir()
{
cout<<vagonszam<<" "<<maxtomb<<endl;
}
int main()
{
Vonat v_52164;
v_52164.beolvas(1);
v_52164.kiir();
Vonat v_54587;
v_54587.beolvas(2);
v_54587.kiir();
return 0;
}
In this code something's wrong, because after running it gets the error message specified before.
Thanks to everyone, who try to help me, all the best.
I have the following C++ code for practising sequence list and it passed the complier. However, when I try to run it, it returns Segmentation fault. Please help!! Thanks a lot.
main.cpp
#include <iostream>
#include <string>
#include "SeqList.h"
using namespace std;
int main() {
SeqList seq;
string vv[] = {"a", "b", "c", "d"};
for (int i = 0; i< 4; i++) {
seq.addElement(vv[i], i);
}
string* v = seq.getSeq();
for (int i=0; i<seq.getSeqSize(); i++) {
cout << v[i] <<endl;
}
return 0;
}
SeqList.h
#include<iostream>
#include<string>
using namespace std;
class SeqList {
private:
string seq[];
int size;
public:
void addElement(string, int);
void delElement(string, int);
string* getSeq();
int getSeqSize();
};
SeqList.cpp
#include <iostream>
#include <string>
#include "SeqList.h"
using namespace std;
string seq[100];
int size = 0;
string* SeqList::getSeq(){
return seq;
};
int SeqList::getSeqSize(){
return size;
};
void SeqList::addElement(string str, int pos) {
int i;
for (i = size; i > pos; i--) {
seq[i] = seq[i-1];
}
seq[i-1] = str;
size++;
};
Your segfault is happening because you're trying to access seq[i-1] in addElement when i = 0. This tries to access the memory outside of seq which causes a segfault. Try using seq[i] and seq[i+1] instead of seq[i-1] and seq[i], though you'll have to make sure you never call that code with more than 99 values or you'll run into a similar problem where the program tries to access memory past the end of seq.
Also, in SeqList.cpp
string seq[100];
int size = 0;
These lines are creating new variables, when it looks like you're trying to change the values you made in SeqList.h. To change those private values in your class you should either use a constructor or other function to initialize the values.
I have been searching all morning how to do this and I can't quite find what I am looking for. I should mention that I am fairly new to C.
I am trying to modulise my code (that is working until I try and do this)
Presently in the main code I have :
#include<stdio.h>
#include<rfftw.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include <fstream>
#include <iomanip>
#include<complex>
#include<omp.h>
struct basic_gal {
double ra,dec,z,dist,fkp,nbar;
double cp[3];
double RSD[3];
};
struct basic_gal *gal;
int NGAL_MAX =200000;
main() {
if(!(gal = (struct basic_gal*)malloc(NGAL_MAX*sizeof(struct basic_gal))-1))
printf("memory allocation problem for galaxies\n");
etc etc..
}
I then go on to read in a file and allocate the various attributes to the structure.
What I would like to do is pass the empty structure (or a pointer to it) to a function, fill in the elements of the structure in the function and then return it to use in my main program again.
This requires 3 files, the main.c, the header file, header.h and the file that contains the function actions bin_gals.c
In the header file I have
#include <stdlib.h>
#include <fstream>
#include <iomanip>
#include <stdio.h>
#include <math.h>
#include <string>
void bin_NGP(int,int*,struct basic_gal*,int);
In the bin_gals.c file I have
#include "header.h"
#include <all_the_others>
void bin_NGP(int NGAL_MAX, int *NGAL, basic_gal *gal, int flag) {
/*read in files and add data etc*/
}
And in the main.c file I have
#include "header.h"
#include <all_the_others>
struct basic_gal {
double ra,dec,z,dist,fkp,nbar;
double cp[3];
double RSD[3];
};
struct basic_gal *gal;
int NGAL_MAX = 200000;
main() {
if(!(gal = (struct basic_gal*)malloc(NGAL_MAX*sizeof(struct basic_gal))-1))
printf("memory allocation problem for galaxies\n");
int NGAL =0;
int *ipNGAL =&NGAL;
bin_NGP(NRAN_MAX,ipNGAL,gal,1);
}
The problem is that I think I am not passing the structure properly but cannot figure out how to do this.
My error messages look like
bin_gals.c: In function ‘void bin_NGP(int, int*, basic_gal*, int)’:
bin_gals.c:150: error: ISO C++ forbids comparison between pointer and integer
bin_gals.c:151: error: invalid types ‘basic_gal*[int*]’ for array subscript
and I am not sure how to fix this.
Any help would be much appreciated!
EDIT: The actual content of the bin_NGP part of bin_gals.c is:
void bin_NGP(const char *data, int NGAL_MAX, int *NGAL, double *min_x, double *min_y ,double *min_z, double *max_x, double *max_y ,double *max_z ,struct basic_gal *gal, int flag) {
FILE *fp_rand;
if((fp_rand=fopen(data,"r"))==NULL) printf("data file %d not opened\n", flag);
const int bsz=100; char buf[bsz];
fgets(buf, bsz, fp_rand); //header line
while((fgets(buf, bsz, fp_rand))!=NULL) {
double ra, dec, cz;
sscanf(buf,"%lf %lf %lf\n",&ra,&dec,&cz);
if(++NGAL>NGAL_MAX) { NGAL--; break; }
gal[NGAL].ra = ra*pi/180.;
gal[NGAL].dec = dec*pi/180.;
gal[NGAL].z = cz;
gal[NGAL].dist = calc_dp(gal[NGAL].z);
gal[NGAL].cp[0] = (gal[NGAL].dist*cos(gal[NGAL].dec)*cos(gal[NGAL].ra));
gal[NGAL].cp[1] = (gal[NGAL].dist*cos(gal[NGAL].dec)*sin(gal[NGAL].ra));
gal[NGAL].cp[2] = (gal[NGAL].dist*sin(gal[NGAL].dec));
if (flag ==1) {
if (gal[NGAL].cp[0] > max_x) max_x = gal[NGAL].cp[0];
if (gal[NGAL].cp[1] > max_y) max_y = gal[NGAL].cp[1];
if (gal[NGAL].cp[2] > max_z) max_z = gal[NGAL].cp[2];
if (gal[NGAL].cp[0] < min_x) min_x = gal[NGAL].cp[0];
if (gal[NGAL].cp[1] < min_y) min_y = gal[NGAL].cp[1];
if (gal[NGAL].cp[2] < min_z) min_z = gal[NGAL].cp[2];
}
}
fclose(fp_rand);
}
I tried to simplify the question by removing some of the input parameters.. maybe I was disguising a mistake.
EDIT: fixed. For clarity I have included the fixed code incase anyone has the same problem.
void bin_NGP(const char *data, int NGAL_MAX, int *NGAL, double *min_x, double *min_y ,double *min_z, double *max_x, double *max_y ,double *max_z ,struct basic_gal *gal, int flag) {
FILE *fp_rand;
if((fp_rand=fopen(data,"r"))==NULL) printf("data file %d not opened\n", flag);
const int bsz=100; char buf[bsz];
fgets(buf, bsz, fp_rand); //header line
while((fgets(buf, bsz, fp_rand))!=NULL) {
double ra, dec, cz;
sscanf(buf,"%lf %lf %lf\n",&ra,&dec,&cz);
if(++(*NGAL) > NGAL_MAX) { *NGAL--; break; }
gal[*NGAL].ra = ra*pi/180.;
gal[*NGAL].dec = dec*pi/180.;
gal[*NGAL].z = cz;
gal[*NGAL].dist = calc_dp(gal[*NGAL].z);
gal[*NGAL].cp[0] = (gal[*NGAL].dist*cos(gal[*NGAL].dec)*cos(gal[*NGAL].ra));
gal[*NGAL].cp[1] = (gal[*NGAL].dist*cos(gal[*NGAL].dec)*sin(gal[*NGAL].ra));
gal[*NGAL].cp[2] = (gal[*NGAL].dist*sin(gal[*NGAL].dec));
if (flag ==1) {
if (gal[*NGAL].cp[0] > *max_x) *max_x = gal[*NGAL].cp[0];
if (gal[*NGAL].cp[1] > *max_y) *max_y = gal[*NGAL].cp[1];
if (gal[*NGAL].cp[2] > *max_z) *max_z = gal[*NGAL].cp[2];
if (gal[*NGAL].cp[0] < *min_x) *min_x = gal[*NGAL].cp[0];
if (gal[*NGAL].cp[1] < *min_y) *min_y = gal[*NGAL].cp[1];
if (gal[*NGAL].cp[2] < *min_z) *min_z = gal[*NGAL].cp[2];
}
}
fclose(fp_rand);
}
You need to forward declare struct basic_gal* for the declaration of bin_NGP() as struct basic_gal is defined in main.c. However, the definition of struct basic_gal will need to be available to the definition of bin_NGP() so you should move its definition out of main.c into a separate module:
/* basic_gal.h */
#ifndef BASIC_GAL_DEFINITION
#define BASIC_GAL_DEFINITION
struct basic_gal {
double ra,dec,z,dist,fkp,nbar;
double cp[3];
double RSD[3];
};
#endif
Note, if this is C you need to use struct basic_gal.
After edit, this is the offending line:
if(++NGAL>NGAL_MAX) { NGAL--; break; }
as NGAL is an int* and NGAL_MAX is an int. Dereference NGAL:
if(++*NGAL > NGAL_MAX) { (*NGAL)--; break; }
Dereference NGAL when using as array index:
gal[*NGAL].ra = ra*pi/180.;
You need to make your structure visible to both main.c and bin_gals.c. Modify your header bin_gals.h to something like:
#include <stdlib.h>
#include <fstream>
#include <iomanip>
#include <stdio.h>
#include <math.h>
#include <string>
struct basic_gal {
double ra,dec,z,dist,fkp,nbar;
double cp[3];
double RSD[3];
};
void bin_NGP(int,int*,struct basic_gal*,int);
bin_gals.c then would look like
#include "bin_gals.h"
#include <all_the_others>
void bin_NGP(int NGAL_MAX, int *NGAL, basic_gal *gal, int flag) {
/*read in files and add data etc*/
}
And your main file would be like the following:
#include "bin_gals.h"
#include <all_the_others>
struct basic_gal *gal;
int NGAL_MAX = 200000;
main() {
if(!(gal = (struct basic_gal*)malloc(NGAL_MAX*sizeof(struct basic_gal))-1))
printf("memory allocation problem for galaxies\n");
int NGAL =0;
int *ipNGAL =&NGAL;
bin_NGP(NRAN_MAX,ipNGAL,gal,1);
}