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.
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.