Memory free error in class SPD

Discussion related to the organization of the source code, repository and code-level/compiler optimization.

Moderator: coordinators

Memory free error in class SPD

Postby cooby » Fri Dec 11, 2009 5:40 am

Hi,

In order to allow user-defined spectral responses for the camera channels, I modified the LuxBlend Python file and the FlexImageFilm class, adding the following lines in the FlexImageFilm::CreateFilm(...) method :
Code: Select all
//**********************************************************************************************************************FC
   //récupération des réponses spectrales de la caméra, données par l'utilisateur :
      
   vector<SPD> vspds;
   
   string spdtype = params.FindOneString("spdtype", "sampled");
   std::stringstream ss; ss << "Camera SPD type : " << spdtype << std::endl;
   luxError(LUX_NOERROR,LUX_INFO, ss.str().c_str() );
   if (spdtype == "sampled")
   {
      u_int nbSamplSPD = params.FindOneInt("nbSamplSPD", 8);
      float fR[nbSamplSPD], fG[nbSamplSPD], fB[nbSamplSPD];
      for (u_int i = 0; i < nbSamplSPD; ++i)
      {
         std::stringstream sstrR;
         sstrR << "valSPDR_" << i;
         fR[i] = params.FindOneFloat(sstrR.str().c_str(), 1.f);
           
         std::stringstream sstrG;
         sstrG << "valSPDG_" << i;
         fG[i] = params.FindOneFloat(sstrG.str().c_str(), 1.f);
           
         std::stringstream sstrB;
         sstrB << "valSPDB_" << i;
         fB[i] = params.FindOneFloat(sstrB.str().c_str(), 1.f);
      }
       
      RegularSPD spdR (fR, WAVELENGTH_START, WAVELENGTH_END, nbSamplSPD);
      RegularSPD spdG (fG, WAVELENGTH_START, WAVELENGTH_END, nbSamplSPD);
      RegularSPD spdB (fB, WAVELENGTH_START, WAVELENGTH_END, nbSamplSPD);
      vspds.push_back(spdR); vspds.push_back(spdG); vspds.push_back(spdB);
   }
   else if (spdtype == "PanchroUniform")
   {
      EqualSPD spd(1.0f);
      vspds.push_back(spd);
      vspds.push_back(spd);
      vspds.push_back(spd);
   }
   else
   {
      //std::cerr << "Unknown SPD type.EqualSPD will be used.\n";
      luxError(LUX_NOERROR,LUX_WARNING, "Unknown SPD type.EqualSPD will be used.");
      EqualSPD spd(1.0f);
      vspds.push_back(spd);
      vspds.push_back(spd);
      vspds.push_back(spd);
   }
   //******************************************************************************
   
   return new FlexImageFilm(xres, yres, filter, crop,
      filename, premultiplyAlpha, writeInterval, displayInterval,
      clampMethod, w_EXR, w_EXR_channels, w_EXR_halftype, w_EXR_compressiontype, w_EXR_applyimaging, w_EXR_gamutclamp, w_EXR_ZBuf, w_EXR_ZBuf_normalizationtype,
      w_PNG, w_PNG_channels, w_PNG_16bit, w_PNG_gamutclamp, w_PNG_ZBuf, w_PNG_ZBuf_normalizationtype,
      w_TGA, w_TGA_channels, w_TGA_gamutclamp, w_TGA_ZBuf, w_TGA_ZBuf_normalizationtype,
      w_resume_FLM, restart_resume_FLM, haltspp, halttime,
      s_TonemapKernel, s_ReinhardPreScale, s_ReinhardPostScale, s_ReinhardBurn, s_LinearSensitivity,
      s_LinearExposure, s_LinearFStop, s_LinearGamma, s_ContrastYwa, s_Gamma,
      red, green, blue, white, reject_warmup, debug_mode, vspds);

Though the spectral densities were well imported from the scene file, the creation of the Film led to a "double free or corruption" error while run with gdb.
After investigation, it was due to a bad behaviour of the SPD copy constructor , so I modified the SPD class :
Code: Select all
//*****************************************************************
SPD::SPD(const SPD & spd2) //copy constructor
{
   samples = NULL;
   *this = spd2;
}


SPD& SPD::operator=(const SPD& spd2)
{
    //std::cerr << "Début de l'opérateur d'affectation. \n" << std::flush;
   nSamples = spd2.nSamples;
   lambdaMin = spd2.lambdaMin;
   lambdaMax = spd2.lambdaMax;
   delta = spd2.delta;
   invDelta = spd2.invDelta;
   if(samples==spd2.samples) return *this;
   AllocateSamples(nSamples);

   for (int k = 0; k < nSamples; ++k) { samples[k] = spd2.samples[k]; }

   return *this;
}
//***************************************************
void SPD::AllocateSamples(u_int n) {
    // Allocate memory for samples
   //********************************
   FreeSamples();
   //***********************
   samples = AllocAligned<float>(n);
}

void SPD::FreeSamples() {
    // Free Allocate memory for samples
   //if (samples)
   //   FreeAligned(samples);
   //***************************
   if (samples != NULL)
   {
      FreeAligned(samples);
      samples = NULL;
   }
   //*******************************
}

Do you think it's a bug that should be fixed in luxrender sources, or is this a malevolent use of the SPD class? :)
cooby
 
Posts: 13
Joined: Tue May 19, 2009 3:33 am
Location: Paris

Re: Memory free error in class SPD

Postby jeanphi » Fri Dec 11, 2009 7:46 am

Hi,

SPD should not be instanced directly, unfortunately it doesn't have any pure virtual method preventing it. Otherwise you wouldn't have been able to define a vector<SPD>, you should instead use a vector<SPD *>, this will prevent the copy constructor from being called.
I do agree though that the SPD class should be improved, but maybe removing the storing of the data and having it in derived classes.

Jeanphi
jeanphi
Developer
 
Posts: 6577
Joined: Mon Jan 14, 2008 7:21 am


Return to Organization & Optimization

Who is online

Users browsing this forum: No registered users and 1 guest