CDirectionalMapGenerator

CDirectionalMapGenerator

我有一个奇怪的访问位置错误,仅在我在IDE外部运行程序时才会发生(我使用Code :: Block和GNU GCC编译器,并使用GBD作为调试器)。

Unhandled exception at 0x77cd82ea in SFinGe.exe: 0xC0000005: Access violation reading location 0x69687065.


当我尝试将元素添加到std :: map时会发生这种情况。我知道,这通常发生在有单位变量的情况下,但是我一直在仔细检查代码,无法找到问题所在,并且使我发狂。

这是类的定义:

//==============================================================================
// CDirectionalMapGenerator prototypes.
//==============================================================================

#ifndef CDIRECTIONALMAPGENERATOR_H
#define CDIRECTIONALMAPGENERATOR_H

//==============================================================================

#include <complex.h>
#include <math.h>
#include <map>
#include <vector>
#include <CRandom.h>
#include <SFingerprintPattern.h>
#include <ESingularityType.h>

//==============================================================================

#define PI 3.14159265359

//==============================================================================

/** \brief
  * Generates a directional map using the orientation model proposed by Sherlock and Monro, this allows a consistent orientation image to be computed from
  * the knowledge of the position of the fingerprint singularities (core and deltas) alone. The image is located in the complex plane and the local ridge
  * orientation is the phase of the square root of a complex rational function whose singularities (poles and zeros) are located at the same place
  * as the fingerprint singularities.
 */
class CDirectionalMapGenerator
{
  public:

    /** \brief
     * Initializes a new instance of the CDirectionalMapGenerator class.
     *
     */
    CDirectionalMapGenerator();

    /** \brief
     * Destroy the CDirectionalMapGenerator object and all its reference safely.
     */
    virtual ~CDirectionalMapGenerator();

    /** \brief
     * Generates a directional map.
     * \param pattern CFingerprintPattern The fingerprint class and singularity types information.
     * \param witdh int The witdh of the map.
     * \param height int The height of the map.
     * \return std::vector<std::vector<double>> The directional map.
     */
    std::vector<std::vector<double> > generate(SFingerprintPattern& pattern, int width, int height);

  private:

    /** \brief
     * Gets the segment orientation.
     * \param z complex The complex number representing a point in the directional map.
     * \return double The segment orientation in radians.
     */
    double getSegmentOrientation(std::complex<double> z);

    /** \brief
     * Vizcaya and Gerhardt correction.
     * \param alpha double The angle to be corrected.
     * \param singularityType ESingularityType The singularity type.
     * \return double The angle corrected.
     */
    double correctOrientation(double alpha, ESingularityType singularityType);

    /** \brief
     * Gets the amount of angle correction for the given point. The directional map is uniformly divided between -PI and PI
     * in eight segments (45 degrees each segment), points in each region must be adjusted using a different piecewise linear function.
     * The variables 'v' and 'u' are angles defined at the beginning of the generation process, this angles are chosen depending on the
     * singularity type and fingerprint class.
     * \param q int Region of the point.
     * \param singularityType ESingularityType The singularity type.
     * \return double The amount of correction.
     */
    double getAmountOfCorrection(int q, ESingularityType singularityType);

    /** \brief
     *  Modification angles must be defined on the basis of position and number of singularities.
     * \return void
     *
     */
    void generateWeigths();

  private:
      static CRandom*                    m_sRandom;

      std::map<ESingularityType, double> m_v;
      std::map<ESingularityType, double> m_u;
      EFingerprintClass                  m_currentFingerprintClass;
      SFingerprintPattern                m_currentPattern;
      double                             m_nArchTypeFactors[3];
      int                                m_nCurrentWidth;
      int                                m_nCurrentHeight;
};


#endif // CDIRECTIONALMAPGENERATOR_H


和实现:

#include "CDirectionalMapGenerator.h"
//==============================================================================

// Static variable initialization.
CRandom* CDirectionalMapGenerator::m_sRandom = new CRandom(time(0));

//==============================================================================
CDirectionalMapGenerator::CDirectionalMapGenerator()
{
    m_currentFingerprintClass = ARCH;
    m_nCurrentWidth           = 0;
    m_nCurrentHeight          = 0;
    m_v                       = std::map<ESingularityType, double>();
    m_u                       = std::map<ESingularityType, double>();
}

//==============================================================================
CDirectionalMapGenerator::~CDirectionalMapGenerator()
{
    delete m_sRandom;

    m_u.clear();
    m_v.clear();
}

//==============================================================================
std::vector<std::vector<double> > CDirectionalMapGenerator::generate(SFingerprintPattern& pattern, int width, int height)
{
    std::vector<std::vector<double> > directionalMap;

    m_currentFingerprintClass = pattern.FingerprintClass;
    m_currentPattern          = pattern;
    m_nCurrentWidth           = width;
    m_nCurrentHeight          = height;

    // Clear weights from last generation.
    m_u.clear();
    m_v.clear();

    this->generateWeigths();

    for (int i = 0; i < m_nCurrentWidth; ++i)
    {
      std::vector<double> vLine;
      for (int j = 0; j < m_nCurrentHeight; ++j)
      {
        std::complex<double> z(i, j);

        vLine.push_back(this->getSegmentOrientation(z));
      }

      directionalMap.push_back(vLine);
    }

    return directionalMap;
}


//==============================================================================
double CDirectionalMapGenerator::getSegmentOrientation(std::complex<double> z)
{
      double segmentOrientation = 0;
      int    degrees            = 0;

      if (m_currentFingerprintClass == ARCH)
      {
        // Arch patterns that do not contain any singularity are not supported by the model, a sinusoidal function
        // must be use instead (The frequency and amplitude are tuned to control the arch curvature and aspect).
        segmentOrientation = atan(std::max(0.0, (m_nArchTypeFactors[2] - m_nArchTypeFactors[2] * z.imag() / (m_nCurrentHeight * m_nArchTypeFactors[1]))) * cos(z.real() * PI / (m_nCurrentWidth * m_nArchTypeFactors[0])));
      }
      else if (m_currentFingerprintClass == WHORL)
      {
        // Whorl have two cores and two deltas.

        // 1/2(g(arg(z - d1)) - g(arg(z - l1))) + 1/2(g(arg(z - d2)) - g(arg (z - l2)))
        segmentOrientation = (0.5 * (this->correctOrientation(arg((z - m_currentPattern.DeltaOne)), DELTA) - this->correctOrientation(arg((z - m_currentPattern.LoopOne)), CORE))) +
                             (0.5 * (this->correctOrientation(arg((z - m_currentPattern.DeltaTwo)), SECONDARY_DELTA) - this->correctOrientation(arg((z - m_currentPattern.LoopTwo)), SECONDARY_CORE)));
      }
      else
      {
        // 1/2(g(arg(z - d)) - g(arg (z - l)))
        segmentOrientation = 0.5 * (this->correctOrientation(arg((z - m_currentPattern.DeltaOne)), DELTA) - this->correctOrientation(arg((z - m_currentPattern.LoopOne)), CORE));
      }

      degrees = static_cast<int>(segmentOrientation * (180 / PI)); // From radiants to degrees.

      if(degrees < 0)
        degrees = -(((-1) * degrees) % (180)) + 180;

      segmentOrientation = degrees * (PI / 180); // From degrees to radiants.

      return segmentOrientation;
}

//==============================================================================
double CDirectionalMapGenerator::correctOrientation(double alpha, ESingularityType singularityType)
{
      int    q             = static_cast<int>(floor(4 * (PI + alpha) / PI));
      double alphaI        = -PI + (PI * q) / 4;
      double correctionOne = this->getAmountOfCorrection(q + 1, singularityType); //gk(alpha i)
      double correctionTwo = this->getAmountOfCorrection(q + 2, singularityType); //gk(alpha i + 1)

      return (correctionOne + ((4 * (alpha - alphaI)) / PI) * (correctionTwo - correctionOne));
}

//==============================================================================
double CDirectionalMapGenerator::getAmountOfCorrection(int q, ESingularityType singularityType)
{
      double amountOfCorrection = 0;
      switch (q)
      {
        case 1:
          amountOfCorrection = -PI + m_u[singularityType];
          break;
        case 2:
          amountOfCorrection = -3 * PI / 4 + m_u[singularityType];
          break;
        case 3:
          amountOfCorrection = -PI / 2;
          break;
        case 4:
          amountOfCorrection = -PI / 4 + m_v[singularityType];
          break;
        case 5:
          amountOfCorrection = m_v[singularityType];
          break;
        case 6:
          amountOfCorrection = PI / 4 + m_v[singularityType];
          break;
        case 7:
          amountOfCorrection = PI / 2;
          break;
        case 8:
          amountOfCorrection = 3 * PI / 4 + m_u[singularityType];
          break;
        default:
          amountOfCorrection = PI + m_u[singularityType];
          break;
      }

      return amountOfCorrection;
}

//==============================================================================
void CDirectionalMapGenerator::generateWeigths()
{
      switch (m_currentFingerprintClass)
      {
        case(ARCH):

          m_nArchTypeFactors[0] = (0.8 + 0.4 * m_sRandom->nextDouble());
          m_nArchTypeFactors[1] = (0.6 + 0.8 * m_sRandom->nextDouble());
          m_nArchTypeFactors[2] = (1.2 + m_sRandom->nextDouble() * 1.5);

        break;
      case (LEFT_LOOP):

          m_u[CORE] = -120 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);
          m_v[CORE] = 50 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);

        break;
      case (RIGHT_LOOP):

          m_u[CORE] = -90 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);
          m_v[CORE] = 60 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);

        break;
      case (TENTED_ARCH):

          m_u[CORE] = -90 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);
          m_v[CORE] = 45 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);

        break;
      case (WHORL):

          // Whorl have two cores and two deltas.
          m_u[CORE] = -60 * PI / 180.0 + m_sRandom->nextDouble() * (15 * PI / 180.0);
          m_v[CORE] = 40 * PI / 180.0 + m_sRandom->nextDouble() * (15 * PI / 180.0);
          m_u[SECONDARY_CORE] = 10 * PI / 180.0 + m_sRandom->nextDouble() * (15 * PI / 180.0);
          m_v[SECONDARY_CORE] = 20 * PI / 180.0 + m_sRandom->nextDouble() * (15 * PI / 180.0);

        break;
      }
          m_u[DELTA] = 0;
          m_v[DELTA] = 0;
          m_u[SECONDARY_DELTA] = 0;
          m_v[SECONDARY_DELTA] = 0;
}


这是打破的方法:

void CDirectionalMapGenerator::generateWeigths()
{
      switch (m_currentFingerprintClass)
      {
        case(ARCH):

          m_nArchTypeFactors[0] = (0.8 + 0.4 * m_sRandom->nextDouble());
          m_nArchTypeFactors[1] = (0.6 + 0.8 * m_sRandom->nextDouble());
          m_nArchTypeFactors[2] = (1.2 + m_sRandom->nextDouble() * 1.5);

        break;
      case (LEFT_LOOP):

          m_u[CORE] = -120 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);
          m_v[CORE] = 50 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);

        break;
      case (RIGHT_LOOP):

          m_u[CORE] = -90 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);
          m_v[CORE] = 60 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);

        break;
      case (TENTED_ARCH):

          m_u[CORE] = -90 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);
          m_v[CORE] = 45 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);

        break;
      case (WHORL):

          // Whorl have two cores and two deltas.
          m_u[CORE] = -60 * PI / 180.0 + m_sRandom->nextDouble() * (15 * PI / 180.0);
          m_v[CORE] = 40 * PI / 180.0 + m_sRandom->nextDouble() * (15 * PI / 180.0);
          m_u[SECONDARY_CORE] = 10 * PI / 180.0 + m_sRandom->nextDouble() * (15 * PI / 180.0);
          m_v[SECONDARY_CORE] = 20 * PI / 180.0 + m_sRandom->nextDouble() * (15 * PI / 180.0);

        break;
      }
          m_u[DELTA] = 0;
          m_v[DELTA] = 0;
          m_u[SECONDARY_DELTA] = 0;
          m_v[SECONDARY_DELTA] = 0;
}


每当我尝试为地图分配值时,它都会失败:

m_u[CORE] = -90 * PI / 180.0 + m_sRandom->nextDouble() * (45 * PI / 180.0);


我不确定会磨损什么,我在构造器中初始化了需要它的所有成员,所有其他成员都作为参数传递给方法“生成”。

我会缺少什么?

最佳答案

您在程序中使用两个CDirectionalMapGenerator吗?静态变量m_sRandom在程序开始时仅被new一次,但是只要delete被销毁,其静态变量CDirectionalMapGenerator d。如果在第一个CDirectionalMapGenerator被销毁后创建第二个m_sRandom,则每当它访问delete时,您将取消引用无效的指针。

确保在程序结束之前不使用m_sRandom指针,或者将其设置为非静态,以便每个CDirectionalMapGenerator实例都有其自己的副本。

关于c++ - 在std::map中插入元素时,仅在 Release模式下访问冲突读取位置“地址”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13943111/

10-11 18:05