Under my button class, I have this function that checks if the mouse is within the bounds of the button:
bool Button::isMouseOver(int mousePosX, int mousePosY) {
if (button.getPosition().x < mousePosX &&
button.getPosition().x + button.getSize().x > mousePosX &&
button.getPosition().y < mousePosY &&
button.getPosition().y + button.getSize().y > mousePosY) {
return true;
}
return false;
}
And then under my main cpp file I have this logic used to activate the function:
int mousePosX = sf::Mouse::getPosition().x;
int mousePosY = sf::Mouse::getPosition().y;
switch (Event.type) {
case sf::Event::Closed:
window.close();
case sf::Event::MouseButtonPressed:
if (btnPlay.isMouseOver(mousePosX, mousePosY)) {
std::cout << "True\n";
}
}
but for some reason, nothing happens. And I know that this can work, because I have the same exact code in one of my other games and it works fine.
Slightly off topic, you comment
And I know that this can work, because I have the same exact code in
one of my other games and it works fine.
triggered me to think You might want to consider generalizing this and making something like
bool IsInside(windowPos wp, windowSize ws, someOtherPos sop) {
if (wp.x < sop.X &&
wp.x + ws.x > sop.X &&
wp.y < sop.Y &&
wp.y + ws.y > sop.Y) {
return true;
}
return false;
}
bool Button::isMouseOver(Vector2i mousePos) {
return IsInside(getPosition(), getSize(), mousePos) ;
}
Note types in IsInside are not exact and might actually be the same ( Vector2i ).
This also makes testing easier for correctness and removes a source of errors with copied code.
Related
if (value >= 2) {
return 1
} else if (value >= 1) {
return 0.9;
} else if (value >= 0.8) {
return 0.7
} else if (value >= 0.5) {
return 0.5;
} else {
return 0;
}
How to solve this if-else ladder. If i use switch cyclometric complexity increases and also also values feels like true.
In some cases the solution is breakaway code. Not everyone likes it - I do like it.
It just means you handle situations "from the top" and end situations with a return
pseudocode in any language...
(Everything should be in a function anyway...)
HandleTemperature(float t)
{
if (t > 90)
{
RunEmergencyCooling();
return;
}
if (round.t == 63)
{
DealWithgMagicValue();
return;
}
if (round.t > 40)
{
Debug.("normal temps! no worries!);
return;
}
// if you get to here, temp is very lopw
RunEmergencyHeating();
}
(In many languages there's a "finally" or "always do" concept, which can work well w/. breakaway dcode.)
Your example ...
Step 1, put in in a function as it should be anyway, Step 2 use "breakaway chunks".
float HandleValue(float v)
{
if (2.0 <= v) {
return 1
}
if (0.7 < v && v < 2.0) {
return 0.9;
}
if (0.13 <= v && v <= 0.7) {
return 17.6;
}
log didn't find a bracket in HandleValue
return default value
}
Every bracket is totally explicit. You can easily build testing code from there, too.
Those annoying long blocks before errors ...
Breakaway is particularly clean-looking in error cases...
Something()
{
if comms.text != 17.2
{
.. 100s of lines of code here ..
.. they are all indented ..
}
else
{
an error!
}
}
Some (but not all) believe this is better:
Something()
{
if comms.text == 17.2
{
an error!
return; .. note the "return" in breakaway code
}
.. 100s of lines of code here ..
.. no need for indentation ..
}
"Breakaway code" may work for you in some cases; in any event you can be aware of the approach.
I have a cat game I have been working on in pygame that I am now writing in c++ SDL2 which are similar. But I have a weird specific problem. A variable in my level.cc class doesn't accrue with old += new in the move() function I am thinking that it is being set to 0 somewhere or my scope is off but I am just lost. I will post the files that are pertinent here and then link to my github as well. I appreciate your time and help.
The level.cc file:
void Level::move(int newx){
groundX += newx;
}
and the cat.cc file:
void Cat::move(int screenSize, Level l){
if((catmX + mVelX > 0) && (catmX + mVelX + (catwidth / 2) < (screenSize * .70))){
catmX += mVelX;
} else if(catmX + mVelX + (catwidth / 2) >= (screenSize * .70)){
l.move(CAT_VEL);
catmY += mVelY;
}
}
and the main:
string grndLoc = "src/grass.png";
Level level1(extra.loadTexture(grndLoc, extra.getRen()), extra.getHeight());
string backgroundImage = "src/sky.png";
SDL_Texture *bck = extra.loadTexture(backgroundImage, extra.getRen());
if(bck == nullptr){
extra.destroyer(bck);
extra.quitGame();
return 1;
}
SDL_Event e;
bool quit = false;
while(!quit){
while(SDL_PollEvent(&e)){
if(e.type == SDL_QUIT){
quit = true;
}
switch(e.key.keysym.sym){
case SDLK_ESCAPE:
quit = true;
break;
}
catplayer.handleEvent(e);
}
SDL_RenderClear(extra.getRen());
extra.renderTexture(bck, extra.getRen(), 0, 0, extra.getWidth(), extra.getHeight());
level1.rend(extra);
extra.renderTexture(catplayer.getTexture(), extra.getRen(), catplayer.getX(), catplayer.getY(), catplayer.getclip());
SDL_RenderPresent(extra.getRen());
catplayer.move(extra.getWidth(), level1);
https://github.com/ironsketch/catGamecpp
My teacher made mention that I was probably calling the constructor somewhere! I found that I was passing a copy of the level and not a pointer to the level!
void Cat::move(int screenSize, Level l){
So I changed it to
void Cat::move(int screenSize, Level *l){
I updated a few other things to reflect that I am now using a pointer and it's fixed! Thanks everyone who responded <3
I am encountering issues with both std::thread and std::mutex, unable to get both to play nicely with each other. I've been pulling my hair out over this for the past few hours and just cannot make any progress whatsoever. I believe it is out of my skill area. The code is just below:
void GekkoFyre::TuiHangouts::gui_userRosterListNav(std::shared_ptr<WINDOW> display,
std::vector<const char *> userList,
const short &menuItem)
{
while (rosterEnabled) {
for (short i = 0; i < totalMenuItems; ++i) {
short diff = (menuItem - i);
if (i < numMenuItems) {
if (i == menuItem) {
size_t msgLen = strlen(userList.at(i));
size_t l = 0;
if (msgLen > subMaxX) {
for (l = subMaxX; l < msgLen; ++l) {
// Scroll the message from left to right, then vice versa, so that it fits within
// the designated window.
std::this_thread::sleep_for(std::chrono::milliseconds(500));
rosterListMutex.lock();
wattron(usrSubWin.get(), A_REVERSE); // Highlight selection
const char *msg = userList.at(i);
mvwaddstr(usrSubWin.get(), i, 0, &msg[(msgLen - l)]);
wrefresh(usrSubWin.get());
touchwin(usrSubWin.get());
rosterListMutex.unlock();
}
} else {
rosterListMutex.lock();
wattron(usrSubWin.get(), A_REVERSE); // Highlight selection
mvwaddstr(usrSubWin.get(), i, 0, userList.at(i));
wrefresh(usrSubWin.get());
touchwin(usrSubWin.get());
rosterListMutex.unlock();
}
}
wattroff(usrSubWin.get(), A_REVERSE); // Remove highlight
if ((i + 1) < numMenuItems) {
mvwaddstr(usrSubWin.get(), (i + 1), 0, userList.at((i + 1)));
}
} else if (diff < (totalMenuItems - numMenuItems) && diff > 0) {
// Allow the scrolling of a username list, from downwards and then back upwards, so that
// the user may see the list in its entirety.
wclear(usrSubWin.get());
int pos = 0;
for (short c = diff; c < (numMenuItems + diff); ++c) {
++pos;
mvwaddstr(usrSubWin.get(), pos, 0, userList.at(c));
}
pos = 0;
break;
}
}
rosterListMutex.lock();
wattroff(usrSubWin.get(), A_REVERSE); // Remove highlight
touchwin(usrSubWin.get());
wrefresh(usrSubWin.get());
wrefresh(display.get());
rosterListMutex.unlock();
}
}
I am trying to display a list of users to the left of a chat window in NCurses, as can be seen in [ 1 ] below, albeit without any users present in said screenshot. I want to keep my privacy :) What happens is that as you scroll down the list, flickering begins to occur back and forth between two usernames after scrolling past just a few. They keep repeatedly selecting each other, just over and over. I believe this is reason of the threads not syncing up properly. The function is implemented as so:
[ 1 ] - http://imgur.com/ZZlFHg2
#define WIDGET_USERS_LIST 1
short menuItem = 0;
int ch = 0;
int curr_widget = 0;
std::thread rosterListNav1(&GekkoFyre::TuiHangouts::gui_userRosterListNav, this, userListWin, rosterFormatted, menuItem);
rosterListNav1.detach();
while ((ch = wgetch(display.get())) != KEY_F(12)) {
switch (ch) {
case KEY_DOWN:
if (curr_widget == WIDGET_USERS_LIST && rosterEnabled) {
++menuItem;
if (menuItem > totalMenuItems - 1) {
menuItem = 0;
}
}
break;
case KEY_UP:
if (curr_widget == WIDGET_USERS_LIST && rosterEnabled) {
--menuItem;
if (menuItem < 0) {
menuItem = totalMenuItems - 1;
}
}
}
std::thread rosterListNav2(&GekkoFyre::TuiHangouts::gui_userRosterListNav, this, userListWin, rosterFormatted, menuItem);
rosterListNav2.detach();
}
Any help on this issue would be dearly appreciated, and I believe I have placed the std::mutex's in the right areas. I am really stumped with this problem. Also beware that while I know a few tricks of the trade, I am entirely self-taught. Some of the nomenclature that is normal to programmers who have gone through university is completely unintelligible to me.
I've come across a situation where I have a bunch of "systems" that need to be initialized in sequence, with the next system only being initialized if all of the proceeding systems initialized successfully.
This has led me to a whole slew of nested if - else statements. Here's some pseudo-code for visualization.
bool mainInit () {
if (!system1Init ()) {
reportError (); // some error reporting function
}
else {
if (!system2Init ()) {
reportError ();
}
else {
if (!system3Init ()) {
// ... and so on
I find that this starts to look like a mess when you get even a handful of levels to it.
Now I thought of using a switch statement instead, starting at the first case and falling through to the other cases on success, only breaking if there's an error.
bool mainInit () {
switch (1) {
case 1:
if (!system1Init ()) {
reportError ();
break;
}
case 2:
if (!system2Init ())
reportError ();
break;
}
// ....
}
Now, I like this a lot better. I find it much easier to read, especially with some decent comments, but I'm fairly new to programming.
So, my question is: Seeing how this is not how switch statements are traditionally used(at least from what I've seen), is something like this acceptable, or would this be considered bad form?
Being new to programming, I'm trying not to develop too many bad habits that might frustrate and make things more difficult for other programmers down the road.
I did a search, but most of what I found had to do with replacing chains of if - else if statements, not replacing nested ones.
Reference all of the systems in an array, for example an std::vector<mySystem*>, and loop over them sequentially, breaking off on the first fail. This way your entire code is reduced to less than 5 lines of code, even for 500+ systems.
The suggested switch hack is an evil example of XY problem solving: your real problem is that you don't have the array of systems, and are using named variables, thus eliminating all options to more flexibly use all systems, like in a loop.
Assuming that all your system#Init() calls are known at compile time, you can very easily put them in a table and then iterate over that table.
typedef (*system_init)(void);
system_init initialization_functions[] =
{
system1Init,
system2Init,
system3Init,
...
systemNInit
};
bool mainInit()
{
for(size_t idx(0); idx < sizeof(initialization_functions) / sizeof(initialization_functions[0]); ++idx)
{
if(!initialization_functions[idx]())
{
ReportError();
return false;
}
}
return true;
}
However, your existing code looks incorrect since the first mainInit() only calls system1Init() and then exits. Probably not what you wanted in the first place.
if(!system1Init())
{
ReportError();
return false;
}
// if you add an else, the system2Init() does not get called
// even if system1Init() succeeds
if(!system2Init())
{
ReportError();
return false;
}
[...]
return true;
Would the switch answer your problem? Not as it was written. That is, if you wanted to call the mainInit() function with a counter, it could be useful. Drupal uses that mechanism:
bool mainInit(int idx)
{
bool r(true);
switch(idx)
{
case 1:
r = system1Init();
break;
case 2:
r = system2Init();
break;
[...]
}
if(!r)
{
ReportError();
}
return r
}
Note that the table mechanism works the same way as the switch. As long as all the code is found in the systemNInit() functions (and it should be), the switch does not add anything, so you could do something like this too:
bool mainInit(int idx)
{
if(idx < 0 || idx >= sizeof(initialization_functions) / sizeof(initialization_functions[0]))
{
throw std::range_error("index out of bounds");
}
if(!initialization_functions[idx]())
{
ReportError();
return false;
}
return true;
}
Calling the mainInit() with an index can be helpful in case you want to "de-initialize" properly:
int main()
{
for(size_t idx(0); idx < ...; ++idx)
{
if(!mainInit(idx))
{
while(idx > 0)
{
--idx;
mainDeinit(idx);
}
exit(1);
}
}
...app do something here...
}
Use custom exceptions with clear error messages and add a try-catch-report-die around the code in main(). Exceptions are there to specifically make your case look good by making "bad path" implicit.
void initX() { ...; throw std::invalid_argument_exception("..."); }
int main() {
try {
init1(); init2(); ... run();
return 0;
} catch (std::exception const& e) {
log(e.what()); exit 42;
}
}
I'd do it this way:
bool mainInit () {
if (!system1Init ()) {
return(false);
}
if (!system2Init ()) {
return(false);
}
if (!system3Init ()) {
return(false);
}
//...
return(true);
}
//...
if(!mainInit()) {
reportError();
}
I am running a program on 2 different machines. On one it works fine without issue. On the other it results in a segmentation fault. Through debugging, I have figured out where the fault occurs, but I can't figure out a logical reason for it to happen.
In one function I have the following code:
pass_particles(particle_grid, particle_properties, input_data, coll_eros_track, collision_number_part, world, grid_rank_lookup, grid_locations);
cout<<"done passing particles"<<endl;
The function pass_particles looks like:
void pass_particles(map<int,map<int,Particle> > & particle_grid, std::vector<Particle_props> & particle_properties, User_input& input_data, data_tracking & coll_eros_track, vector<int> & collision_number_part, mpi::communicator & world, std::map<int,int> & grid_rank_lookup, map<int,std::vector<double> > & grid_locations)
{
//cout<<"east-west"<<endl;
//east-west exchange (x direction)
map<int, vector<Particle> > particles_to_be_sent_east;
map<int, vector<Particle> > particles_to_be_sent_west;
vector<Particle> particles_received_east;
vector<Particle> particles_received_west;
int counter_x_sent=0;
int counter_x_received=0;
for(grid_iter=particle_grid.begin();grid_iter!=particle_grid.end();grid_iter++)
{
map<int,Particle>::iterator part_iter;
for (part_iter=grid_iter->second.begin();part_iter!=grid_iter->second.end();)
{
if (particle_properties[part_iter->second.global_part_num()].particle_in_box()[grid_iter->first])
{
//decide if a particle has left the box...need to consider whether particle was already outside the box
if ((part_iter->second.position().x()<(grid_locations[grid_iter->first][0]) && part_iter->second.position().x()>(grid_locations[grid_iter->first-input_data.z_numboxes()][0]))
|| (input_data.periodic_walls_x() && (grid_iter->first-floor(grid_iter->first/(input_data.xz_numboxes()))*input_data.xz_numboxes()<input_data.z_numboxes()) && (part_iter->second.position().x()>(grid_locations[input_data.total_boxes()-1][0]))))
{
particles_to_be_sent_west[grid_iter->first].push_back(part_iter->second);
particle_properties[particle_grid[grid_iter->first][part_iter->first].global_part_num()].particle_in_box()[grid_iter->first]=false;
counter_sent++;
counter_x_sent++;
}
else if ((part_iter->second.position().x()>(grid_locations[grid_iter->first][1]) && part_iter->second.position().x()<(grid_locations[grid_iter->first+input_data.z_numboxes()][1]))
|| (input_data.periodic_walls_x() && (grid_iter->first-floor(grid_iter->first/(input_data.xz_numboxes()))*input_data.xz_numboxes())>input_data.xz_numboxes()-input_data.z_numboxes()-1) && (part_iter->second.position().x()<(grid_locations[0][1])))
{
particles_to_be_sent_east[grid_iter->first].push_back(part_iter->second);
particle_properties[particle_grid[grid_iter->first][part_iter->first].global_part_num()].particle_in_box()[grid_iter->first]=false;
counter_sent++;
counter_x_sent++;
}
//select particles in overlap areas to send to neighboring cells
else if ((part_iter->second.position().x()>(grid_locations[grid_iter->first][0]) && part_iter->second.position().x()<(grid_locations[grid_iter->first][0]+input_data.diam_large())))
{
particles_to_be_sent_west[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
else if ((part_iter->second.position().x()<(grid_locations[grid_iter->first][1]) && part_iter->second.position().x()>(grid_locations[grid_iter->first][1]-input_data.diam_large())))
{
particles_to_be_sent_east[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
++part_iter;
}
else if (particles_received_current[grid_iter->first].find(part_iter->first)!=particles_received_current[grid_iter->first].end())
{
if ((part_iter->second.position().x()>(grid_locations[grid_iter->first][0]) && part_iter->second.position().x()<(grid_locations[grid_iter->first][0]+input_data.diam_large())))
{
particles_to_be_sent_west[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
else if ((part_iter->second.position().x()<(grid_locations[grid_iter->first][1]) && part_iter->second.position().x()>(grid_locations[grid_iter->first][1]-input_data.diam_large())))
{
particles_to_be_sent_east[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
part_iter++;
}
else
{
particle_grid[grid_iter->first].erase(part_iter++);
counter_removed++;
}
}
}
world.barrier();
mpi::request reqs_x_send[particles_to_be_sent_west.size()+particles_to_be_sent_east.size()];
vector<multimap<int,int> > box_sent_x_info;
box_sent_x_info.resize(world.size());
vector<multimap<int,int> > box_received_x_info;
box_received_x_info.resize(world.size());
int counter_x_reqs=0;
//send particles
for(grid_iter_vec=particles_to_be_sent_west.begin();grid_iter_vec!=particles_to_be_sent_west.end();grid_iter_vec++)
{
if (grid_iter_vec->second.size()!=0)
{
//send a particle. 50 will be "west" tag
if (input_data.periodic_walls_x() && (grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes()))*input_data.xz_numboxes()<input_data.z_numboxes()))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1)], grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1), particles_to_be_sent_west[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1)]].insert(pair<int,int>(world.rank(), grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1)));
}
else if (!(grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes()))*input_data.xz_numboxes()<input_data.z_numboxes()))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()], grid_iter_vec->first - input_data.z_numboxes(), particles_to_be_sent_west[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()]].insert(pair<int,int>(world.rank(),grid_iter_vec->first - input_data.z_numboxes()));
}
}
}
for(grid_iter_vec=particles_to_be_sent_east.begin();grid_iter_vec!=particles_to_be_sent_east.end();grid_iter_vec++)
{
if (grid_iter_vec->second.size()!=0)
{
//send a particle. 60 will be "east" tag
if (input_data.periodic_walls_x() && (grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes())*input_data.xz_numboxes())>input_data.xz_numboxes()-input_data.z_numboxes()-1))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1)], 2000000000-(grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1)), particles_to_be_sent_east[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1)]].insert(pair<int,int>(world.rank(),2000000000-(grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1))));
}
else if (!(grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes())*input_data.xz_numboxes())>input_data.xz_numboxes()-input_data.z_numboxes()-1))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()], 2000000000-(grid_iter_vec->first + input_data.z_numboxes()), particles_to_be_sent_east[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()]].insert(pair<int,int>(world.rank(), 2000000000-(grid_iter_vec->first + input_data.z_numboxes())));
}
}
}
counter=0;
for (int i=0;i<world.size();i++)
{
//if (world.rank()!=i)
//{
reqs[counter++]=world.isend(i,1000000000,box_sent_x_info[i]);
reqs[counter++]=world.irecv(i,1000000000,box_received_x_info[i]);
//}
}
mpi::wait_all(reqs, reqs + world.size()*2);
//receive particles
//receive west particles
for (int j=0;j<world.size();j++)
{
multimap<int,int>::iterator received_info_iter;
for (received_info_iter=box_received_x_info[j].begin();received_info_iter!=box_received_x_info[j].end();received_info_iter++)
{
//receive the message
if (received_info_iter->second<1000000000)
{
//receive the message
world.recv(received_info_iter->first,received_info_iter->second,particles_received_west);
//loop through all the received particles and add them to the particle_grid for this processor
for (unsigned int i=0;i<particles_received_west.size();i++)
{
particle_grid[received_info_iter->second].insert(pair<int,Particle>(particles_received_west[i].global_part_num(),particles_received_west[i]));
if(particles_received_west[i].position().x()>grid_locations[received_info_iter->second][0] && particles_received_west[i].position().x()<grid_locations[received_info_iter->second][1])
{
particle_properties[particles_received_west[i].global_part_num()].particle_in_box()[received_info_iter->second]=true;
}
counter_received++;
counter_x_received++;
}
}
else
{
//receive the message
world.recv(received_info_iter->first,received_info_iter->second,particles_received_east);
//loop through all the received particles and add them to the particle_grid for this processor
for (unsigned int i=0;i<particles_received_east.size();i++)
{
particle_grid[2000000000-received_info_iter->second].insert(pair<int,Particle>(particles_received_east[i].global_part_num(),particles_received_east[i]));
if(particles_received_east[i].position().x()>grid_locations[2000000000-received_info_iter->second][0] && particles_received_east[i].position().x()<grid_locations[2000000000-received_info_iter->second][1])
{
particle_properties[particles_received_east[i].global_part_num()].particle_in_box()[2000000000-received_info_iter->second]=true;
}
counter_received++;
counter_x_received++;
}
}
}
}
mpi::wait_all(reqs_y_send, reqs_y_send + particles_to_be_sent_bottom.size()+particles_to_be_sent_top.size());
mpi::wait_all(reqs_z_send, reqs_z_send + particles_to_be_sent_south.size()+particles_to_be_sent_north.size());
mpi::wait_all(reqs_x_send, reqs_x_send + particles_to_be_sent_west.size()+particles_to_be_sent_east.size());
cout<<"x sent "<<counter_x_sent<<" and received "<<counter_x_received<<" from rank "<<world.rank()<<endl;
cout<<"rank "<<world.rank()<<" sent "<<counter_sent<<" and received "<<counter_received<<" and removed "<<counter_removed<<endl;
cout<<"done passing"<<endl;
}
I only posted some of the code (so ignore the fact that some variables may appear to be undefined, as they are in a portion of the code I didn't post)
When I run the code (on the machine in which it fails), I get done passing but not done passing particles
I am lost as to what could possibly cause a segmentation fault between the end of the called function and the next line in the calling function and why it would happen on one machine and not another.
If you're crashing between the end of a function and the subsequent line in the caller, you're probably crashing in the destructor of a local variable. You need to run the program in a debugger to find out which object's destructor is crashing.
There are a couple of possibilities:
You actually are returning, but cout is buffered by the OS so you don't see "done passing particles" because the application crashes first.
You have some local class that has a destructor that is seg faulting.
Try running it in a debugger to find out where it is actually crashing.
Edit:
Since you've mentioned you're using gcc, add the -g flag and run it with gdb. Gdb will then tell you exactly where it's going wrong (probably a null dereference).
Just in case anyone comes back to this later. I updated to the newest version of boost mpi(at the time), 1.50 and this issue went away. Not much of a solution, but it worked.