0

IDE の外部でプログラムを実行した場合にのみ発生する奇妙なアクセス ロケーション エラーがあります (GNU GCC コンパイラと GBD をデバッガとして使用している Code::Block を使用しています)。

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);

コンストラクターで必要なすべてのメンバーを初期化しました。他のすべてのメンバーはパラメーターとしてメソッド「生成」に渡されます。

何が欠けている可能性がありますか?

4

1 に答える 1

3

プログラムで2つのを使用CDirectionalMapGeneratorしていますか?静的変数m_sRandomは、プログラムの開始時に1回だけnew編集されますが、aが破棄さdeleteれるたびにdになります。CDirectionalMapGenerator最初のポインタが破棄された後に2番目のポインタを作成するCDirectionalMapGeneratorと、アクセスするたびにm_sRandom無効なポインタが逆参照されます。

プログラムの最後までポインタを置かないようにするかdelete、の各インスタンスが独自のコピーを持つm_sRandomように非静的にします。CDirectionalMapGenerator

于 2012-12-18T23:20:44.817 に答える