Reputation: 4421
I am now working on a rather complex project involving control of a simulated robotic arm. I finished a first version of the project and it is working fine. I just added some new code that collect some information about the system at each iteration, save it in some arrays, and at the end prints everything in a file for later analysis.
Now, something real strange is happening. If I define the file in which the data will be saved as follow:
const std::string SAVEFILE = "C:\\Users\\Vincent\\Desktop\\ta";
everything works fine, exactly the same as it did before I add the new code (plus saving the data).
But if I define it as follow:
const std::string SAVEFILE = "C:\\Users\\Vincent\\Desktop\\tacit.txt";
then the system behaves in another way. Does not crash, but the robotic arm moves differently.
I tried to comment all the code that was making use of SAVEFILE, and even any new code related to data saving, but the problem persists.
I know that with only this information, it is unlikely that anybody can tell me what is wrong, but would anybody have some advice what direction to look ? Would it make sense to think that a long string overwrite the value of some other variable ? How can it be possible ? Some guideline of clean C++ programming I might have broken ?
That some array is misbehaving sounds possible, and was the first thing I checked. I guess it should come from the arrays saving data, as they are the only new one. Thing is, even when I comment all the corresponding code, no change.
I try to give more information about my code. Here where I first use SAVEFILE (last argument of the runExperiment function)
int main(int argc, char *argv[]) {
std::vector<Controller*> controllers;
controllers.push_back(getConstrainedPDT(0,true));
controllers.push_back(getConstrainedPDT(1,true));
controllers.push_back(getConstrainedPDT(2,true));
runExperiment(controllers,LENGTHS,WEIGHTS,RADIUS,ANGLEMIN,ANGLEMAX,MAXTORQUES,PUSHVECTOR,GRAVITY,RUNTIME,TIMESTEP,XTARGET,YTARGET,ITERATIONSAVEDATA,SAVEFILE);
return 1;
}
and here the code of the function:
void runExperiment(std::vector<Controller*> controllers,const double * lengths, const double* weights, const double radius, const double* angleMin, const double* angleMax, const double* maxTorques,const double* pushVector,const dReal gravity,const dReal runTime,const dReal tstep,const dReal targetX,const dReal targetY,const int itSaveData,const std::string saveFile){
endTime = runTime;
simTime = 0.0;
timeStep = tstep;
dInitODE();
world = dWorldCreate();
space = dHashSpaceCreate(0);
contactgroup = dJointGroupCreate(0);
ground = dCreatePlane(space, 0, 0, 1, 0);
dWorldSetGravity(world, 0, 0, gravity);
createTargetObject(targetX,targetY);
int nbData = static_cast<int>( ( endTime / timeStep ) / static_cast<double>(itSaveData) );
robot = new R2DRobot(&world,controllers.size(),lengths,weights,radius,angleMin,angleMax,maxTorques,pushVector,controllers,itSaveData,nbData);
dsFunctions fn;
fn.version = DS_VERSION;
fn.start = &setViewPoint;
fn.step = &loop;
fn.stop = &stopSim;
fn.path_to_textures = PATH_TO_TEXTURES;
dsSimulationLoop(0, 0, 1280, 960, &fn);
dWorldDestroy(world);
dCloseODE();
// NOTE: commenting the next three lines does not fix the problem !
// it is the only place saveFile is used, except in the code of printData
// I do not show the code of printData as commenting it does not change anything
if (itSaveData>0){
robot->printData(saveFile);
}
delete robot;
}
In the hope to find the unspecified variable (not that easy for a project with a lot of classes, some of them virtual), I played with the const parameters and observed the behavior of the robot. I reached a situation:
works fine all the time:
const std::string SAVEFILE = "C:\\Users\\Vincent\\Desktop\\tacit.txt";
crashes the program:
const std::string SAVEFILE = "C:\\Users\\Vincent\\Desktop\\ta";
Now the issue is, if I add a single line to the code of runExperiment (call to printf added):
printf("experiment.cpp - 1 \n");
robot = new R2DRobot(&world,controllers.size(),lengths,weights,radius,angleMin,angleMax,maxTorques,pushVector,controllers,itSaveData,nbData);
then both versions of SAVEFILE work fine and do give exactly similar results.
Now, if I delete the call to printf and add in the constructor of R2DRobot:
R2DRobot::R2DRobot(dWorldID * world, const int nbLinks, const double * lengths, const double * weights, const double radius,const double* angleMin,const double* angleMax,const double* maxTorques,const double* pushVector, std::vector<Controller*> controllers,int saveData,int nbData):
Robot(3*nbLinks+3,controllers),pushVector(pushVector),nbLinks(nbLinks),weights(weights),angleMin(angleMin),angleMax(angleMax),maxTorques(maxTorques),itSaveData(saveData){
printf("experiment.cpp - 1 \n");
// rest of the code
then the program crashes (if using the short version of SAVEFILE) but after printing "experiment.cpp -1" in the console.
Same thing if I move the call to printf to the constructor of Robot, the mother class of R2DRobot.
Upvotes: 1
Views: 411
Reputation: 3571
The height number of arguments to runExperiment
with are global variables are telling you that you may need a higher level object to wrap and organize it. While trying to write a constructor for such an object you will probably see and correct the problem with the incorrect/un-initialized variables, with will prevent undefined behavior.
Upvotes: 1
Reputation: 116177
This might be manifestation that your program does not initialize variables properly. When string was shorter, compiler created certain memory layout, and variables created on a stack (or on a heap) had certain values. By pure luck, those values were something that seemed to work right for you.
Now, since string has become longer, compiler has changed memory layout a little, and this led to slightly different layout. Now, these uninitialized variables might have slightly different values. It does not necessarily crash, but works differently.
Upvotes: 8
Reputation: 38173
but would anybody have some advice what direction to look
This information is really not enough, unfortunately. Maybe, you can try using valgrind
or a similar tool to analyze your code.
Would it make sense to think that a long string overwrite the value of some other variable? How can it be possible?
No, this is not a long string. It's not even close to long string. If the string is too long, you'll have an exception for invalid length.
Some guideline of clean C++ programming I might have broken
Not enough information. Using std::string
is good and it's even recommended.
The problem is somewhere else. Sounds like undefined behavior to me.
Upvotes: 2