I am currently working in C++ and I face this challenge. Here is a code of my class in the header file:
class PID
{
private:
int PID;
int total;
public:
PID(); // Constructor
int returnPID(); // Returns PID.
};
Here is the code declaration in cpp file:
PID::PID()
{
PID=INT_MAX;
total=0;
}
int PID::returnPID()
{
return PID;
}
And here is the declaration and the initialization in main of a table contaning pointers to objects of the class PID:
PID* table[1000000];
for (int i=0; i<1000000; i++)
{
table[i]=new PID;
}
So I suppose this uses the constructor I have created above to set the PID to MAX_INT. When I try to access the content of table[i].PID using returnPID within the initialization for everything works great, something like this:
for (int i=0; i<1000000; i++)
{
table[i]=new PID;
int display=table[i]->returnPID();
cout<<display<<endl;
}
The problem occurs when I am trying to access table[i] contents outside and after the initialization for. My main crashes and it returns a number (-1073741571) as an error. It seems like not even one command from the main is executed. Here is a sample of the code that seems to reproduce the problem:
for (int i=0; i<1000000; i++)
{
table[i]=new PID;
}
for (int i=0; i<1000000; i++)
{
int display=table[i]->returnPID();
cout<<display<<endl;
}
I have been working on this for more than two hours without coming to any solution and it just doesn't seem logical. Anyone have any explanation for this?
EDIT: Any table with less than 1.000.000 spots will work correctly. Maybe it has something to do with this although I still don't see the connection.
Anyone have any explanation for this?
It seems like you're running out of stack space.
Can your compiler handle a million integers, instead of a million PID*?
Any table with less than 1.000.000 spots will work correctly. Maybe it
has something to do with this although I still don't see the
connection.
It has everything to do with that.
I tried this:
int main(){
int bec[10000000];
for (int i=0; i<10000000;i++){
bec[i] = i;
}
printf("%d\n",rand()%1000);
return 0;
}
It segfaults for the same reason as yours.
The only way to solve this problem is to use less stack space. You can declare bec outside of main and not use stack space for that or you can use std::vector. You have plenty of options.
PID* table[1000000];
There's your problem. That's an automatically-allocated array of 1,000,000 pointers, or [up to] eight million bytes. Stack space is often fairly limited and you're using a lot of it. When I say "limited", I mean like 8KB, not 8MB.
When you go over this, often the results are not pretty.
8MB is a lot for automatic allocation (what you may call "on the stack"); so, look into adjusting your storage mechanism, or consider using dynamic allocation — how about a nice std::vector?
BTW.. having a member variable with the same name as the class it's in is silly.
Related
class RF
{
public:
bitset<32> ReadData1, ReadData2;
RF()
{
Registers.resize(32);
Registers[0] = bitset<32> (0);
}
void ReadWrite(bitset<5> RdReg1, bitset<5> RdReg2, bitset<5> WrtReg, bitset<32> WrtData, bitset<1> WrtEnable)
{
// implement the funciton by you.
}
void OutputRF() // write RF results to file
{
ofstream rfout;
rfout.open("RFresult.txt",std::ios_base::app);
if (rfout.is_open())
{
rfout<<"A state of RF:"<<endl;
for (int j = 0; j<32; j++)
{
rfout << Registers[j]<<endl;
}
}
else cout<<"Unable to open file";
rfout.close();
}
private:
vector<bitset<32> >Registers;
};
RF() is the constructor, but since all it does is resize Registers to 32, you can remove it if you specify that initialization on the member directly, like this:
vector<bitset<32> > Registers = vector<bitset<32> >(32);
Then Registers will be constructed with size 32x32 bits by default, and all the bits will be zero as well, so you can remove the entire RF() function.
Note: At first I thought you could use vector<bitset<32> > Registers{32} but due to vagaries of C++ syntax that does the wrong thing. Thanks to Fureeish for that.
The short answer to your question is that, yes, for your current program, it is necessary.
The RF() function in this case is the function called when we initialize the RF object, eg.
RF new_RF;
Would run the RF() function and set things up. For this reason, it is called a 'constructor', because it helps you 'construct' your class.
In your case, the constructor is necessary for your program because it sets up your Registers variable, so that the code below from your OutputRF() function can run.
for (int j = 0; j<32; j++)
{
rfout << Registers[j]<<endl;
}
It's also useful because we can use it to set up many things, for example, if our RF() constructor looked like this:
RF(int a)
{
Registers.resize(a);
Registers[0] = bitset<a> (0);
}
It would instead resize the RF Registers to int a. You can look here for a more in-depth tutorial about constructors.
Hope that helps!
I have developed a program in C++11 and I want to speed up the performance.
I will use a simple example to show the structure of the program (not complete).
//main.cpp
#include "a.h"
int main()
{
std::vector<a> a_container;
for (auto i=0; i< 10K; i++)
{
a a_obj;
a_container.push_back(a_obj);
}
for(time = 1; time< long_time; time++)
{
//i used openmp here already
for (auto i=0; i< 10K; i++)
{
a_container[i].dosomething();
}
for (auto i=0; i< 10K; i++)
{
a_container[i].update();
}
}
return 1;
}
//a.cpp
//a.h
#include "b.h"
class a
{
int d;
b b_obj;
int dosomething();
}
//b.cpp
//b.h
class b
{
int c;
double d;
int dosomething();
}
So in order to speed up the program, I want to use both MPI and OpenMP, mainly for the loop (could be up to 1 million~1 billion instances).
The class object a and b both contain complex member variables (standard and other containers, etc.) and functions.
By using OpenMP, I can take advantage of one HPC node with all cores/threads. But if I want to use MPI, I need to distribute all the instances to many nodes.
I haven't found a good solution to this yet, the closest thing I have right now is;
http://mpi-forum.org/docs/mpi-2.2/mpi22-report/node83.htm#Node83
and https://blogs.cisco.com/performance/how-to-send-cxx-stl-objects-in-mpi
Please provide some suggestion. Thanks.
Sending non-trivially-copyable objects over MPI is just the same as sending them over any other byte transport: you have to serialize. You can use stringstream to hold the buffer on either end, if it helps.
However, it’s very likely that you shouldn’t do this at all. The data needed to create your objects (e.g., loop bounds and initial values) is probably much smaller and simpler than the form used for ongoing computation. Send that instead, and you can create your complicated objects in parallel as well as reducing communication. (If the parameters are known statically, you don’t have to send anything: each process can just start working on the known initialization.)
Our teacher told us to create a vector of objects and perform operations on it, but I couldn't understand how to properly do that: I tried to make a simple project with minimum data so that I could know what I was doing.
I have this class
class Obj {
private:
int num;
public:
Obj();
void setNum(int nuovo_num);
int getNum();
};
And then this one, with a vector of Obj
class VettObj{
private:
vector<Obj> vett;
public:
VettObj();
void setVett();
void stampaVett();
};
My initial thought was to use an iterator but I was just making a total mess and, with almost useless research, I decided to use a common integer counter.
I found that I shouldn't write anything in the VettObj costructor, as it automatically initialize stuff, so I left it blank.
The method that adds elements is this
void VettObj::setVett(){
Obj temp;
int i;
i = 0;
while(i < 5){
temp.setNum(10);
vett.push_back(temp);
i++;
}
}
And the one that prints elements
void VettObj::stampaVett(){
int i;
i = 0;
while(i < 5){
vett[i].getNum();
i++;
}
}
When I compile, everything goes well, but when I run the program I get nothing on the screen. I don't want to use mostly vector functions(if not necessary) as I saw that a lot of people can do it like this. I would really like to know how to do it with iterators too. Help pls ????
You are not actually printing anything in the stampaVett() method.
You could try with:
void VettObj::stampaVett(){
int i = 0;
while (i < 5){
std::cout << vett[i].getNum();
i++;
}
}
I'd also suggest using English for method or variable instead of Italian, since SO is an international community.
I'm currently trying to work with vectors / deques of structures. Simple example of the structure...
struct job {
int id;
int time;
}
I want to be able to search through the structure to find the job that matches the time, remove it from the structure and continue to check for other ids in that structure. Sample code...
<vector> jobs;
<deque> started;
for (unsigned int i = 0; i < jobs.size(); i++)
{
if (jobs.at(i).time == time)
{
started.push_back(jobs.at(i));
jobs.erase(jobs.begin() + i);
i--;
}
}
time++;
This works how I want it to but it also seems very hacky since I'm adjusting the index whenever I delete and I think it's simply because I'm not as knowledgeable as should be with data structures. Anyone able to give me some advice?
NOTE - I don't think this is a duplicate to what this post has been tagged to as I'm not looking to do something efficiently with what I already have. To me, it seems efficient enough considering I'm reducing the size of the deque each time I get what I need from it. What I was hoping for, is some advice on figuring out what is the best data structure for what I'm attempting to do with deques, which are likely not meant to be handled as I'm handling them.
I could also be wrong and my usage is fine but just seems off to me to.
Well, I always knew that this talk would come in handy! The message here is "know your STL algorithms". With that, let me introduce you to std::stable_partition.
One thing you can do is use just one single vector, as follows:
using namespace std;
vector<job> jobs;
// fill the vector with jobs
auto startedJobsIter = stable_partition(begin(jobs), end(jobs),
[=time](job const &_job) { return _job.time == time; });
Now, everything between begin(jobs) and startedJobsIter satisfy the condition, while everything from startedJobsIter and end(jobs) does not.
Edit
If you don't care about the relative ordering of the items, then you could just use std::partition, which could be even more performant, because it would not preserve the relative ordering of the elements in the original vector, but will still divide it into the two parts.
Edit 2
Here's an adaptation for older C++ standards:
struct job_time_predicate {
public:
job_time_predicate(int time) : time_(time) { }
bool operator()(job const &the_job) { return the_job.time == time_; }
private:
int time_;
};
int main()
{
using namespace std;
int time = 10;
vector<job> jobs;
// fill that vector
vector<job>::iterator startedJobsIter =
stable_partition(jobs.begin(), jobs.end(), job_time_predicate(time));
}
I have a program that defines changes the target function of a function pointer from within the function being called by said pointer, like so:
void increment(int&);
void superincrement(int&);
void (*fooncrement)(int&);
int main() {
int j = 0;
fooncrement = increment;
while (true == true) {
fooncrement(j);
}
}
void increment(int& i) {
static int counter = 0;
i++;
if (counter > 7)
fooncrement = superincrement;
counter++;
}
void superincrement(int& i) {
i += 23;
}
A quick run through MSVC's debugger shows that the program more or less works as expected. However, are there are any problems not immediately obvious here that might manifest if I tried something like this in a more complex environment?
This is well-defined.
In fact, this technique is often used to implement state machines.
No, there shouldn't be any problem. It's not like it clings to that pointer once you made the call.
This isn't thread-safe, but for single-threaded apps, no problems. If you don't know what threading is, then you're not using it, so you have no problem.
More advanced programs use multiple "threads", each of which is basically it's own program, but they work together. Imagine if you had int main(), but also int main1(), int main2(), int main3(), and they all ran at the same time. Your program could do four things at once! However, if one thread changes fooncrement, there will be a slight delay before the other threads see the updated value. In the meantime, they'd use the old value, which might cause problems.