Выбрасывается исключение в 2х поточной программе

Задача распараллелить вычисление выражения MA = max(Z)*MO+e*(MT*MS) в 2х потоках, где e-константа, Z-вектор, а MA, MO, MT, MS-матрицы. Использовать семафоры, мьютексы, события, критические секции. Все этапы указаны в коде комментариями. Но при запуске выбрасывается исключение:

Вызвано исключение по адресу 0x006A454A в PPKS_Lab1_Win32.exe: 0xC0000005: нарушение прав доступа при записи по адресу 0xCDCDCDCD.

Собственно, код:

#include <iostream>
#include <Windows.h>

using namespace std;

typedef int* vector;
typedef int** matrix;

const int N = 100;
const int P = 2;
const int H = N / P;

int e, m;
vector Z = new int[N];
matrix MO = new vector[N], MT = new vector[N],
MS = new vector[N], MA = new vector[N];

HANDLE E_12, E_21;
HANDLE Mtx;
HANDLE sem1, sem2, semMA;
CRITICAL_SECTION CrSection;
/*=============================T1=============================*/
void T1() {
    int e1, m1, s;
    matrix MT1 = new vector[N];
    for (int i = 0; i < N; i++)
    {
        MT1[i] = new int[N];
    }
    cout << "\nThread T1 started" << endl;
    //1. Введення MT, Z, e
    matrix MA = new vector[N];
    for (int i = 0; i < N; i++) {
        MA[i] = new int[N];
    }
    e = 1;
    for (int i = 0; i < N; i++)
    {
        MT[i] = new int[N];
    }
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            MT[i][j] = 1;
        }
    }
    vector Z = new int[N];
    for (int i = 0; i < N; i++) {
        Z[i] = 1;
    }
    //2.Сигнал задачі Т2 про введення MT, Z, e
    SetEvent(E_12);
    //3.Чекати на введення MO, MS у задачі Т2
    WaitForSingleObject(E_21, INFINITE);
    //4.Обчислення m1 := max(ZH)
    m1 = 0;
    for (int i = 0; i < H; i++)
    {
        if (Z[i] > m1) {
            m1 = Z[i];
        }
    }
    //5.Обчислення m := max (m, m1)
    EnterCriticalSection(&CrSection);
    m = max(m, m1);
    LeaveCriticalSection(&CrSection);
    //6.Сигнал T2 про завершення обчислень m
    ReleaseSemaphore(sem1, 1, NULL);
    //7.Чекати на завершення обчислень m в T2
    WaitForSingleObject(sem2, INFINITE);
    //8.Копіювати MT1 := MT
    EnterCriticalSection(&CrSection);
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            MT1[i][j] = MT[i][j];
        }
    }
    LeaveCriticalSection(&CrSection);
    //9.Копіювати e1 := e
    EnterCriticalSection(&CrSection);
    e1 = e;
    LeaveCriticalSection(&CrSection);
    //10.Копіювання m1 := m
    WaitForSingleObject(Mtx, INFINITE);
    m1 = m;
    ReleaseMutex(Mtx);
    //11.Обчислення MAH = m∙MOH + e∙(MT∙MSH)
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < N; j++) {
            s = 0;
            for (int k = 0; k < N; k++) {
                s += MS[i][k] * MT1[k][j];
            }
            MA[i][j] = m1 * MO[i][j] + e1 * s;
        }
    }
    //12.Чекати на завершення обчислень A в T2
    WaitForSingleObject(semMA, INFINITE);
    //13.Виведення MA
    if (N < 10) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                cout << MA[i][j] << " ";
            }
            cout << endl;
        }
    }
    cout << "\nThread T1 finished" << endl;
}
/*=============================T2=============================*/
void T2() {
    int e2, m2, s;
    matrix MT2 = new vector[N];
    for (int i = 0; i < N; i++)
    {
        MT2[i] = new int[N];
    }
    cout << "\nThread T2 started" << endl;
    //1.Введення MO, MS
    for (int i = 0; i < N; i++)
    {
        MO[i] = new int[N];
        MS[i] = new int[N];
    }
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            MO[i][j] = 1;
            MS[i][j] = 1;
        }
    }
    //2.Сигнал задачі Т1 про введення MO, MS
    SetEvent(E_21);
    //3.Чекати на введення MT, Z, e у задачі Т1
    WaitForSingleObject(E_12, INFINITE);
    //4.Обчислення m2 := max(ZH)
    m2 = 0;
    for (int i = H; i < 2 * H; i++)
    {
        if (Z[i] > m2) {
            m2 = Z[i];
        }
    }
    //5.Обчислення m: = max(m, m2)
    EnterCriticalSection(&CrSection);
    m = max(m, m2);
    LeaveCriticalSection(&CrSection);
    //6.Сигнал T1 про завершення обчислень m
    ReleaseSemaphore(sem2, 1, NULL);
    //7.Чекати на завершення обчислень m в T1
    WaitForSingleObject(sem1, INFINITE);
    //8.Копіювати MT2 := MT
    EnterCriticalSection(&CrSection);
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            MT2[i][j] = MT[i][j];
        }
    }
    LeaveCriticalSection(&CrSection);
    //9.Копіювати e2:= e
    EnterCriticalSection(&CrSection);
    e2 = e;
    LeaveCriticalSection(&CrSection);
    //10.Копіювання m2: = m
    WaitForSingleObject(Mtx, INFINITE);
    m2 = m;
    ReleaseMutex(Mtx);
    //11.Обчислення MAH = m∙MOH+e∙(MT∙MSH)
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < N; j++) {
            s = 0;
            for (int k = 0; k < N; k++) {
                s += MS[i][k] * MT2[k][j];
            }
            MA[i][j] = m2 * MO[i][j] + e2 * s;
        }
    }
    //12.Сигнал T1 про завершення обчислень A
    ReleaseSemaphore(semMA, 1, NULL);
    cout << "\nThread T2 finished" << endl;
}

int main(int argc, char* argv[]) {
    cout << "Started Lab1" << endl;

    E_12 = CreateEvent(NULL, TRUE, FALSE, NULL);
    E_21 = CreateEvent(NULL, TRUE, FALSE, NULL);

    InitializeCriticalSection(&CrSection);

    Mtx = CreateMutex(NULL, FALSE, NULL);

    sem1 = CreateSemaphore(NULL, 0, 1, NULL);
    sem2 = CreateSemaphore(NULL, 0, 1, NULL);
    semMA = CreateSemaphore(NULL, 0, 1, NULL);

    DWORD Tid1, Tid2;
    HANDLE threads[] = {
        CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)T1, NULL, NULL, &Tid1),
        CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)T2, NULL, NULL, &Tid2)
    };

    WaitForMultipleObjects(2, threads, true, INFINITE);
    CloseHandle(threads[0]);
    CloseHandle(threads[1]);

    cout << "Ended Lab2" << endl;
    system("pause");
    return 0;
}

Ответы (0 шт):