Ошибка: нарушения доступа чтения

97
26 июня 2021, 00:10

Имеется программа, которая пересекает 2 многоугольника (std::vector RealSector(1), std::vector MirrorSector(1);). Количество пересеченных точек сокращается (std::vector SendForSaving(1)) до ~50 путем записи в std::vector SendForSaving(1) не всех точек с учетом, что есть так называемые "важные точки" (POINT VIPdots[6]). Все это дело параллельно отрисовывается посередине экрана с помощью метода Polygon (POINT *...). В дополнительном окошке отрисовывается то, что будет сохранено. Возникает проблема при запуске и может выдать 2 вида ошибок (см. рисунки). Обе пишут о нарушении доступа при чтении, хотя, как мне кажется, с выделением и освобождением памяти проблем нет. В чем может быть причина ошибок и как исправить. Спасибо.

// NewClippingDlg.cpp : implementation file
//
#include "stdafx.h"
#include "NewClipping.h"
#include "NewClippingDlg.h"
#include "afxdialogex.h"
#include "clipper.hpp"
#include <gdiplusgraphics.h>
#include "gdiplusgraphics.h"
#include <math.h>
#include <fstream>
#include <gdiplus.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#define PI 3.1415926535
#endif

// CNewClippingDlg dialog
using namespace ClipperLib;
CNewClippingDlg::CNewClippingDlg(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_NEWCLIPPING_DIALOG, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CNewClippingDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_SLIDER1, SectorSlider);
    DDX_Control(pDX, IDC_SLIDER2, XSlider);
    DDX_Control(pDX, IDC_SLIDER3, YSlider);
    DDX_Control(pDX, IDC_SLIDER4, RadiusSlider);
    DDX_Control(pDX, IDC_SLIDER5, AngleSlider);
    DDX_Control(pDX, IDC_CHECK1, CheckSave);
    DDX_Control(pDX, IDC_EDIT7, FirstCts);
    DDX_Control(pDX, IDC_EDIT8, SecondCds);
    DDX_Control(pDX, IDC_CHECK2, DrawStart);
    DDX_Control(pDX, IDC_CHECK3, CheckDrawSaving);
}
BEGIN_MESSAGE_MAP(CNewClippingDlg, CDialogEx)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BUTTON1, &CNewClippingDlg::AddMirrorLine)
    ON_BN_CLICKED(IDC_BUTTON2, &CNewClippingDlg::Activate)
    ON_WM_LBUTTONDOWN()
    ON_WM_HSCROLL()
    ON_BN_CLICKED(IDC_BUTTON3, &CNewClippingDlg::SaveCoordinates)
    ON_BN_CLICKED(IDC_CHECK1, &CNewClippingDlg::IfChecking)
END_MESSAGE_MAP()

// CNewClippingDlg message handlers
BOOL CNewClippingDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
    // TODO: Add extra initialization here
    return TRUE;  // return TRUE  unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.
int X1, Y1, X2, Y2, CenterX, CenterY, StatusLButton = 0, CounterClicks = 0,
    DrawCircles = 0, DrawSolution = 0, NumberOfFile = 0, CON = 0, CenterSmallX, CenterSmallY;
double Step = 1;
long double idouble/*, PI = 3.1415926535*/;
RECT WindowRect;
CRect DrawRect, DrawSavingRect;
std::vector<Path> RealSector(1);
std::vector<Path> MirrorSector(1);
std::vector<Path> SolutionSector(2);
std::vector<Path> SendForSaving(1);
POINT *RealSectorStruct;
POINT *MirrorSectorStruct;
POINT **SolutionStruct;
POINT *FormRealCircle(int XSlider, int YSlider, int AngleSlider, int SectorSlider, int RadiusSlider);
POINT *FormMirrorCircle(POINT *RealSectorStruct, int SectorSlider);
POINT **SolutionCircle(std::vector<Path> SubjectSector, std::vector<Path> ClipperSector);
CString TextForLine, FileName, DirectPathName, ForNumber;
ofstream file;
void SaveCoordinatesFunction();
POINT VIPdots[6];
int VIPDraw = 0;
int k = 0;
POINT *DrawWhatInSave;
int neededsize = 0, WriteHappend = 0;
int CustomSize = 0, CustomStep = 0;
POINT *FormStructForSave(POINT **SolutionStruct);
void CNewClippingDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting
        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
        CWnd* m_hWnd = AfxGetApp()->GetMainWnd();
        m_hWnd->MoveWindow(0, 0, 100, 100);
        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CPaintDC dc(this);
        CPen p(PS_SOLID, 1, RGB(255, 0, 0)), p1(PS_SOLID, 1, RGB(0, 255, 0)), p2(PS_SOLID, 1, RGB(0, 0, 255));
        if (CenterX != 0 && CenterY != 0) {
            dc.Rectangle(DrawRect);
            dc.Rectangle(DrawSavingRect);
        }
        if (X1 != 0 && Y1 != 0 && X2 != 0 && Y2 != 0) {
            dc.MoveTo(X1, Y1);
            dc.LineTo(X2, Y2);
        }
        if (DrawCircles == 1) {
            dc.Polygon(RealSectorStruct, 362 - SectorSlider.GetPos());
            dc.Polygon(MirrorSectorStruct, 362 - SectorSlider.GetPos());
        }
        if (DrawSolution != 0) {
            dc.SelectObject(p);
            for (int i = 0; i < DrawSolution; i++) {
                dc.Polygon(SolutionStruct[i], SolutionSector[i].size());
                if (DrawStart.GetCheck() == 1) {
                    dc.Ellipse(SolutionStruct[i][0].x - 3, SolutionStruct[i][0].y - 3, SolutionStruct[i][0].x + 3, SolutionStruct[i][0].y + 3);
                }
            }
        }
        if (VIPDraw == 1) {
            dc.SelectObject(p1);
            for (int i = 0; i < k + 1; i++) {
                dc.Ellipse(VIPdots[i].x - 3, VIPdots[i].y - 3, VIPdots[i].x + 3, VIPdots[i].y + 3);
            }
        }
        if (neededsize > 0 && CheckDrawSaving.GetCheck() == 1){
            dc.SelectObject(p2);
            dc.Polygon(DrawWhatInSave, neededsize);
        }
    }
}
// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CNewClippingDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}
void CNewClippingDlg::AddMirrorLine()
{
    StatusLButton = 1;
}
void CNewClippingDlg::Activate()
{
    GetClientRect(&WindowRect);
    CenterX = (WindowRect.left + WindowRect.right) / 2;
    CenterY = (WindowRect.top + WindowRect.bottom) / 2;
    CenterSmallX = CenterX - 325;
    CenterSmallY = CenterY;
    DrawRect.left = CenterX - 225;
    DrawRect.top = CenterY - 225;
    DrawRect.right = CenterX + 225;
    DrawRect.bottom = CenterY + 225;
    DrawSavingRect.left = CenterX - 405;
    DrawSavingRect.top = CenterY - 80;
    DrawSavingRect.right = CenterX - 245;
    DrawSavingRect.bottom = CenterY + 80;
    XSlider.SetRange(75, 375, 1);
    XSlider.SetPos(225);
    YSlider.SetRange(75, 375, 1);
    YSlider.SetPos(225);
    AngleSlider.SetRange(0, 360, 1);
    AngleSlider.SetPos(0);
    RadiusSlider.SetRange(10, 75, 1);
    RadiusSlider.SetPos(75);
    SectorSlider.SetRange(0, 360, 1);
    SectorSlider.SetPos(90);
    CheckDrawSaving.SetCheck(1);
    InvalidateRect(DrawRect, 1);
    InvalidateRect(DrawSavingRect, 1);
    OnPaint();
}

void CNewClippingDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
    int Coords[4];
    if (StatusLButton == 1) {
        CounterClicks++;
        if (CounterClicks == 1) {
            Coords[0] = point.x;
            Coords[1] = point.y;
            X1 = Coords[0];
            Y1 = Coords[1];
        }
    }
    if (StatusLButton == 1 && CounterClicks == 2) {
        Coords[2] = point.x;
        Coords[3] = point.y;
        X2 = Coords[2];
        Y2 = Coords[3];
        StatusLButton = 0;
        CounterClicks = 0;
        DrawCircles = 1;
        RealSectorStruct = FormRealCircle(XSlider.GetPos() - 225, YSlider.GetPos() - 225, AngleSlider.GetPos(), SectorSlider.GetPos(), RadiusSlider.GetPos());
        MirrorSectorStruct = FormMirrorCircle(RealSectorStruct, SectorSlider.GetPos());
        SolutionStruct = SolutionCircle(RealSector, MirrorSector);
        DrawWhatInSave = FormStructForSave(SolutionStruct);
        InvalidateRect(DrawRect, 1);
        InvalidateRect(DrawSavingRect, 1);
        OnPaint();
        TextForLine.Format(_T("(%d; %d)"), X1, Y1);
        FirstCts.SetWindowTextW(TextForLine);
        TextForLine.Format(_T("(%d; %d)"), X2, Y2);
        SecondCds.SetWindowTextW(TextForLine);
        XSlider.EnableWindow(true);
        YSlider.EnableWindow(true);
        AngleSlider.EnableWindow(true);
        RadiusSlider.EnableWindow(true);
        SectorSlider.EnableWindow(true);
        delete[] RealSectorStruct;
        delete[] MirrorSectorStruct;
        delete[] SolutionStruct;
        delete[] DrawWhatInSave;
    }
    CDialogEx::OnLButtonDown(nFlags, point);
}
POINT *FormRealCircle(int XSlider, int YSlider, int AngleSlider, int SectorSlider, int RadiusSlider) {
    if (DrawCircles == 1) {
        RealSectorStruct = new POINT[362 - SectorSlider];
        RealSector[0].clear();
        for (int i = 0 + AngleSlider; i < 362 + AngleSlider - SectorSlider; i++) {
            idouble = (long double)i;
            RealSector[0] << IntPoint((CenterX + XSlider + RadiusSlider * cos(idouble*(PI / 180)))*pow(10.0, 6.0),
                (CenterY + YSlider + RadiusSlider * sin(idouble*(PI / 180)))*pow(10.0, 6.0));
            RealSectorStruct[i - AngleSlider].x = CenterX + XSlider + RadiusSlider * cos(idouble*(PI / 180));
            RealSectorStruct[i - AngleSlider].y = CenterY + YSlider + RadiusSlider * sin(idouble*(PI / 180));
        }
        RealSector[0] << IntPoint((CenterX + XSlider)*pow(10.0, 6.0), (CenterY + YSlider)*pow(10.0, 6.0));
        RealSectorStruct[362 - SectorSlider - 1].x = CenterX + XSlider;
        RealSectorStruct[362 - SectorSlider - 1].y = CenterY + YSlider;
        return RealSectorStruct;
    }
}
POINT *FormMirrorCircle(POINT *RealSectorStruct, int SectorSlider) {
    long double k, X0, Y0;
    long double dX1 = (long double)X1;
    long double dY1 = (long double)Y1;
    long double dX2 = (long double)X2;
    long double dY2 = (long double)Y2;
    MirrorSectorStruct = new POINT[362 - SectorSlider];
    MirrorSector[0].clear();
    for (int i = 0; i < 362 - SectorSlider; i++) {
        k = -1 * ((dX2 - dX1)*(dX1 - RealSectorStruct[i].x) + (dY2 - dY1)*(dY1 - RealSectorStruct[i].y)) /
            ((dX2 - dX1)*(dX2 - RealSectorStruct[i].x) + (dY2 - dY1)*(dY2 - RealSectorStruct[i].y));
        X0 = (dX1 + k * dX2) / (1 + k);
        Y0 = (dY1 + k * dY2) / (1 + k);
        MirrorSector[0] << IntPoint(int(2 * X0 - RealSectorStruct[i].x)*pow(10.0, 6.0), int(2 * Y0 - RealSectorStruct[i].y)*pow(10.0, 6.0));
        MirrorSectorStruct[i].x = int(2 * X0 - RealSectorStruct[i].x);
        MirrorSectorStruct[i].y = int(2 * Y0 - RealSectorStruct[i].y);
    }
    return MirrorSectorStruct;
};
POINT **SolutionCircle(std::vector<Path> SubjectSector, std::vector<Path> ClipperSector) {
    VIPDraw = 0;
    SolutionSector.clear();
    Clipper DoClip;
    DoClip.AddPath(SubjectSector[0], ptSubject, true);
    DoClip.AddPath(ClipperSector[0], ptClip, true);
    DoClip.Execute(ctIntersection, SolutionSector, pftNonZero, pftNonZero);
    if (SolutionSector.size() != 0) {
        SolutionStruct = new POINT*[SolutionSector.size()];
        for (int i = 0; i < SolutionSector.size(); i++) {
            SolutionStruct[i] = new POINT[SolutionSector[i].size()];
            for (int j = 0; j < SolutionSector[i].size(); j++) {
                SolutionStruct[i][j].x = SolutionSector[i][j].X / pow(10.0, 6.0);
                SolutionStruct[i][j].y = SolutionSector[i][j].Y / pow(10.0, 6.0);
            }
            DrawSolution = i + 1;
        }
        for (int i = 0; i < SolutionSector.size(); i++) {
            for (int j = 0; j < SolutionSector[i].size(); j++) {
                if ((abs(SolutionStruct[i][j].x - SolutionStruct[i][j + 1].x) > 5 ||
                    abs(SolutionStruct[i][j].y - SolutionStruct[i][j + 1].y) > 5) && j != SolutionSector[i].size() - 1) {
                    VIPdots[k].x = SolutionStruct[i][j].x;
                    VIPdots[k].y = SolutionStruct[i][j].y;
                    VIPdots[k + 1].x = SolutionStruct[i][j + 1].x;
                    VIPdots[k + 1].y = SolutionStruct[i][j + 1].y;
                    k = k + 2;
                    VIPDraw = 1;
                }
                if (j == SolutionSector[i].size() - 1) {
                    if ((abs(SolutionStruct[i][j].x - SolutionStruct[i][0].x) > 5 ||
                        abs(SolutionStruct[i][j].y - SolutionStruct[i][0].y) > 5))
                    VIPdots[k].x = SolutionStruct[i][j].x;
                    VIPdots[k].y = SolutionStruct[i][j].y;
                }
            }
        }
        return SolutionStruct;
    }
    else {
        DrawSolution = 0;
        return 0;
    }
}
void CNewClippingDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    CSliderCtrl *pSlider = reinterpret_cast<CSliderCtrl*>(pScrollBar);
    if (pSlider == &XSlider || pSlider == &YSlider || pSlider == &AngleSlider || pSlider == &SectorSlider || pSlider == &RadiusSlider) {
        k = 0;
        RealSectorStruct = FormRealCircle(XSlider.GetPos() - 225, YSlider.GetPos() - 225, AngleSlider.GetPos(), SectorSlider.GetPos(), RadiusSlider.GetPos());
        MirrorSectorStruct = FormMirrorCircle(RealSectorStruct, SectorSlider.GetPos());
        SolutionStruct = SolutionCircle(RealSector, MirrorSector);
        DrawWhatInSave = FormStructForSave(SolutionStruct);
        if (CheckSave.GetCheck() == 1) {
            SaveCoordinatesFunction();
        }
        InvalidateRect(DrawRect, 1);
        InvalidateRect(DrawSavingRect, 1);
        OnPaint();
        delete[] RealSectorStruct;
        delete[] MirrorSectorStruct;
        delete[] SolutionStruct;
        delete[] DrawWhatInSave;
    }
    CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CNewClippingDlg::SaveCoordinates()
{
    if (SolutionSector.size() != 1) {
        AfxMessageBox(_T("Секторы не пересекаются или пересечение не односвязно"), MB_ICONINFORMATION);
    }
    else {
        SaveCoordinatesFunction();
    }
}
void SaveCoordinatesFunction() {
    if (SendForSaving.size() == 1) {
        if (DirectPathName == "") {
            CFileDialog SFile(false, _T(".txt"), _T("Example 1"), 0, _T("TXT Files (*.txt)|*.txt|"));
            SFile.DoModal();
            DirectPathName = SFile.GetFolderPath();
        }
        NumberOfFile++;
        ForNumber.Format(_T("%d"), NumberOfFile);
        FileName = DirectPathName + _T("\\Example ") + ForNumber + _T(".txt");
        file.open(FileName, ios::out);
        if (file.is_open()) {
            for (int i = 0; i < SendForSaving[0].size(); i++) {
                file << SendForSaving[0][i].X << " " << SendForSaving[0][i].Y << endl;
            }
            file.close();
        }
    }
}
POINT *FormStructForSave(POINT **SolutionStruct)
{
    if (SolutionSector.size() != 0) {
        neededsize = 0;
        WriteHappend = 0;
        DrawWhatInSave = new POINT[SolutionSector[0].size()];
        //for (int i = 0; i < SolutionSector.size(); i++) {
            if (SolutionSector[0].size() > 50) {
                CustomStep = ceil(SolutionSector[0].size() / 50) + 1;
                CustomSize = (SolutionSector[0].size() / CustomStep) + 6;
            }
            else {
                CustomSize = SolutionSector[0].size();
                CustomStep = 1;
            }
            DrawWhatInSave = new POINT[CustomSize];
            for (int j = 0; j < SolutionSector[0].size(); j++) {
                WriteHappend = 0;
                for (int k = 0; k < 6; k++) {
                    if (SolutionStruct[0][j].x == VIPdots[k].x && SolutionStruct[0][j].y == VIPdots[k].y) {
                        DrawWhatInSave[neededsize].x = CenterSmallX - (CenterX - SolutionStruct[0][j].x);
                        DrawWhatInSave[neededsize].y = CenterSmallY - (CenterY - SolutionStruct[0][j].y);
                        neededsize++;
                        WriteHappend = 1;
                        break;
                    }
                }
                if (WriteHappend == 1) {
                    continue;
                }
                else {
                    if (j % CustomStep == 0) {
                        DrawWhatInSave[neededsize].x = CenterSmallX - (CenterX - SolutionStruct[0][j].x);
                        DrawWhatInSave[neededsize].y = CenterSmallY - (CenterY - SolutionStruct[0][j].y);
                        neededsize++;
                    }
                }
            }
        //}
        SendForSaving[0].clear();
        for (int i = 0; i < neededsize; i++) {
            SendForSaving[0] << IntPoint((DrawWhatInSave[i].x - CenterSmallX + CenterX) * 0.5, (DrawWhatInSave[i].y - CenterSmallY + CenterY) * 0.5);
        }
        return DrawWhatInSave;
    }
    else {
        return 0;
    }
}
void CNewClippingDlg::IfChecking()
{
    if (DirectPathName == "") {
        CFileDialog SFile(false, _T(".txt"), _T("Example 1"), 0, _T("TXT Files (*.txt)|*.txt|"));
        SFile.DoModal();
        DirectPathName = SFile.GetFolderPath();
        SaveCoordinatesFunction();
    }
    if (CON % 2 == 0) {
        CON++;
        AfxMessageBox(_T("Включена функция автосохранения.\nПри каждои изменении любого из ползунка будет сохранен новый файл"), MB_ICONINFORMATION);
    }
    else {
        CON++;
        AfxMessageBox(_T("Функция автосохранения отключена"), MB_ICONWARNING);
    }
}
Answer 1

Задача решена. Ошибка была в выделении памяти для DrawWhatInSave. Нужно выделить количество памяти, равное размеру SolutionSector[0].

READ ALSO
Поддержка C++ в Netbeans 11

Поддержка C++ в Netbeans 11

Поставил в Linux MInt среду Netbeans 110

103
Как используют библиотеки с разными версиями языка в одном проекте?

Как используют библиотеки с разными версиями языка в одном проекте?

Собственно, вопрос в заголовкеНа сколько я понял, разные версии языка вводят разные ограничения и предоставляют разные возможности

78
Быстрый поиск процесса по имени

Быстрый поиск процесса по имени

Необходимо максимально быстро найти процесс по названию исполняемого файлаПоиск выполняется из 32 битного приложения, искомый процесс может...

87
Подсчёт кол-во символов в PlainTextEdit

Подсчёт кол-во символов в PlainTextEdit

Как подсчитать кол-во символов введённых в поле QPlainTextEdit? Я еще новичок в теме QT и в С++ в целом, но кое что уже умею, иду на новые высоты)

69