Answer the question
In order to leave comments, you need to log in
Weird winAPI memory access error. How to decide?
I wanted to write a program for drawing the Sperinsky triangle.
#include <windows.h>
#include <conio.h>
#define _USE_MATH_DEFINES
#include <cmath>
#define GREEN RGB(138, 179, 45)
#define RED RGB(181,2,51)
/*Settings*/
#define DELY 0
#define N 14
#define LEN 900
#define AGL 0
#define COLOR GREEN
double* lineFrom(HDC hDC, double x, double y, double l, double angle) {
Sleep(DELY);
double dX = l*cos(angle), dY = l*sin(angle);
double* res = new double[2];
res[0] = x + dX;
res[1] = y + dY;
MoveToEx(hDC, x, y, NULL);
LineTo(hDC, res[0], res[1]);
return res;
}
double getRad(double grad) {
return (grad / 180) * M_PI;
}
double middle(double a, double b) {
return (a - b) / 2 + b;
}
double* triangle(HDC hDC, double x, double y, double a, double angle = 0) {
double* buff = new double[2];
double* bPoint = new double[4];
buff[0] = x; buff[1] = y;
angle += getRad(60);
buff = lineFrom(hDC, buff[0], buff[1], a, angle);
bPoint[0] = buff[0]; bPoint[1] = buff[1];
buff = lineFrom(hDC, buff[0], buff[1], a, angle += getRad(120));
bPoint[2] = buff[0]; bPoint[3] = buff[1];
buff = lineFrom(hDC, buff[0], buff[1], a, angle += getRad(120));
return bPoint;
}
double geth(double a) {
return a * sqrt(3) / 2;
}
void cut(HDC hDC, double* PT, double a, size_t n, double angle = 0) {
double* D = new double[2];
a /= 0;
D[0] = middle(PT[0], PT[2]);
D[1] = middle(PT[1], PT[3]);
double* sP = triangle(hDC, D[0], D[1], a, angle - getRad(180));
n -= 1;
if (n > 0) {
double* sp2 = new double[4];
cut(hDC, sP, a, n, angle);
sp2[0] = D[0]; sp2[1] = D[1];
sp2[2] = PT[2]; sp2[3] = PT[3];
cut(hDC, sp2, a, n, angle);
sp2[0] = PT[0]; sp2[1] = PT[1];
sp2[2] = D[0]; sp2[3] = D[1];
cut(hDC, sp2, a, n, angle);
}
}
void main() {
HWND hwnd;
char Title[1024];
GetConsoleTitle(Title, 1024);
hwnd = FindWindow(NULL, Title);
RECT rc;
GetClientRect(hwnd, &rc);
int iWidth = rc.right;
int iHeight = rc.bottom;
HDC hdc = GetDC(hwnd);
HPEN p1, p2 = CreatePen(PS_SOLID, 2, COLOR);
p1 = (HPEN)SelectObject(hdc, p2);
double curX, curY;
curX = (iWidth) / 2;
curY = (iHeight - geth(LEN)) / 2;
double* bPoint = triangle(hdc, curX, curY, LEN, getRad(AGL));
cut(hdc, bPoint, LEN, N, getRad(AGL));
SelectObject(hdc, p1);
ReleaseDC(hwnd, hdc);
DeleteObject(p2);
_getch();
}
#include <windows.h>
#include <conio.h>
#define _USE_MATH_DEFINES
#include <cmath>
#define GREEN RGB(138, 179, 45)
#define RED RGB(181,2,51)
/*Settings*/
#define DELY 0
#define N 4
#define LEN 900
#define AGL 0
#define COLOR GREEN
double getRad(double grad) {
return (grad / 180) * M_PI;
}
double middle(double a, double b) {
return (a - b) / 2 + b;
}
double geth(double a) {
return a * sqrt(3) / 2;
}
double* lineFrom(HDC hDC, double x, double y, double l, double angle) {
Sleep(DELY);
double dX = l*cos(angle), dY = l*sin(angle);
double* res = new double[2];
res[0] = x + dX;
res[1] = y + dY;
MoveToEx(hDC, x, y, NULL);
LineTo(hDC, res[0], res[1]);
return res;
}
double* triangle(HDC hDC, double x, double y, double a, double angle = 0) {
double* buff = new double[2];
double* bPoint = new double[4];
buff[0] = x; buff[1] = y;
angle += getRad(60);
buff = lineFrom(hDC, buff[0], buff[1], a, angle);
bPoint[0] = buff[0]; bPoint[1] = buff[1];
buff = lineFrom(hDC, buff[0], buff[1], a, angle += getRad(120));
bPoint[2] = buff[0]; bPoint[3] = buff[1];
buff = lineFrom(hDC, buff[0], buff[1], a, angle += getRad(120));
return bPoint;
}
void cut(HDC hDC, double* PT, double a, size_t n, double angle = 0) {
/* Создание массива A для аргументов размером [1][4] */
double **A, **B;
A = new double*[1];
A[0] = new double[4];
/* Инициализация A начальными значениями */
A[0][0] = PT[0]; A[0][1] = PT[1];
A[0][2] = PT[2]; A[0][3] = PT[3];
for (int i = 0; i < n; ++i) {
B = new double*[(i+1) * 3];
a /= 2;
for (int j = 0; j < pow(3, i); ++j) {
/* Буффер данных для след. итерации*/
for(int k = 0; k < 3; ++k)
B[3 * j + k] = new double[4]; // Нужно ли создавать или достаточно присвоить?
/* Обрезаем для текущего */
double D[2] = {
middle(A[j][0], A[j][2]),
middle(A[j][1], A[j][3])
};
double* buff = triangle(hDC, D[0], D[1], a, angle - getRad(180));
/* Расчет параметров для j+1 и запись их в В*/
B[3 * j + 0][0] = buff[0]; B[3 * j + 0][1] = buff[1];
B[3 * j + 0][2] = buff[2]; B[3 * j + 0][3] = buff[3];
B[3 * j + 1][0] = D[0]; B[3 * j + 1][1] = D[1];
B[3 * j + 1][2] = A[j][0]; B[3 * j + 1][3] = A[j][1];
B[3 * j + 2][0] = A[j][2]; B[3 * j + 2][1] = A[j][3];
B[3 * j + 2][2] = D[0]; B[3 * j + 2][3] = D[1];
delete[] A[j];
}
delete[] A; // Нужно ли удалять или достаточно приравнять?
}
}
void main() {
HWND hwnd;
char Title[1024];
GetConsoleTitle(Title, 1024);
hwnd = FindWindow(NULL, Title);
RECT rc;
GetClientRect(hwnd, &rc);
int iWidth = rc.right;
int iHeight = rc.bottom;
HDC hdc = GetDC(hwnd);
HPEN p1, p2 = CreatePen(PS_SOLID, 2, COLOR);
p1 = (HPEN)SelectObject(hdc, p2);
double curX, curY;
curX = (iWidth) / 2;
curY = (iHeight - geth(LEN)) / 2;
double* bPoint = triangle(hdc, curX, curY, LEN, getRad(AGL));
cut(hdc, bPoint, LEN, N, getRad(AGL));
SelectObject(hdc, p1);
ReleaseDC(hwnd, hdc);
DeleteObject(p2);
_getch();
}
Answer the question
In order to leave comments, you need to log in
1. FOR EACH NEW OPERATION, THERE SHOULD BE A CORRESPONDING DELETE OPERATION.
You are clearly missing delete in different places.
2. Use two-dimensional arrays as you use them ... well, this is some kind of perversion. Is that how they teach now? I understand that it is convenient to do [i][j] ... but there is also address arithmetic, denaming. And you can easily go from a pointer to a two-dimensional array, to a pointer to a one-dimensional and use indexing on a one-dimensional array.
3. No need to allocate memory at each iteration of the loop - it is enough to allocate an array of the maximum size at the very beginning, and then use it inside the loop at all iterations.
4.Usually, just recursion is more gluttonous to memory (and to the CPU) than the iterative method, because recursion eats up the stack and if there is a large nesting, then the stack may end.
PS: about the memory error: run the program under the debugger, it will break when an error occurs, in the debugger you can go to your last function (along the call stack) and see where something is wrong (I hope you don't think that the error is really in lineTo ).
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question