Место чтения нарушения доступа & quot; адрес & quot; только в режиме релиза при вставке элементов в std :: map

У меня странная ошибка доступа, которая возникает, только когда я запускаю программу вне 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);

Я не уверен, в чем дело, я инициализировал все члены, которые нуждаются в этом в конструкторе, все остальные передаются в качестве параметров в метод «генерировать».

Чего мне не хватает?

0

Решение

Вы используете два CDirectionalMapGeneratorв вашей программе? Ваша статическая переменная m_sRandom только newодин раз в начале программы, но deleteд всякий раз, когда CDirectionalMapGenerator уничтожен Если вы создаете второй CDirectionalMapGenerator после того, как первый уничтожен, всякий раз, когда он получает доступ m_sRandom вы будете разыменовывать неверный указатель.

Либо убедитесь, что вы не delete m_sRandom указатель до конца вашей программы или сделать его нестатичным, чтобы каждый экземпляр CDirectionalMapGenerator имеет свою копию.

3

Другие решения

Других решений пока нет …