Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Win API проблемы с выделением памяти

76K
17 ноября 2011 года
MeGusta
5 / / 17.11.2011
Всем привет.
Делаю программу с использованием функций Win API. Переделывал под себя чужой пример. Суть в том, что программа создает в файле подкачки отображение файла, в которое нужно записать массив из целых чисел. Прога выдает ошибку при выводе массива на экран. Может подскажет кто, как можно поправить? Сам я в этом не силен, по учебе задание дали. Код ниже.

Код:
#include <iostream>
#include <Windows.h>
#include <tchar.h>
#include <string.h>
#include <strsafe.h>

using namespace std;

#define BUF_SIZE 256*256 //Размер отображаемого файла
#define MAX_AR_LENGHT 20

HANDLE mapFileHandle; //дескриптор отображения файла
int intAr[MAX_AR_LENGHT];       //объявление массива
int *pintAr = intAr; //указатель на массив

void initialize(){

    mapFileHandle = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BUF_SIZE, TEXT("IntFile")); //создаем отображение файла
    if(mapFileHandle = NULL)    //проверяем успешность создания
    {  
        cout<<"ERROR: unable to create map of file";
        exit(0);
    }

    //отображение файла на pintAr
    pintAr =  (int*) MapViewOfFile(mapFileHandle, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, 0 );

    if(pintAr = NULL)   //проверяем успешность отображения
    {  
        cout<<"ERROR: unable to create map of file";
        exit(0);
    }
}

void randomize() //заполнение массива случайными числами в диапазоне 1..100
{
    int * p = pintAr;//Временный указатель на массив
    for(int i = 0; i<=19; i++)
    {
        srand(100);
        p = rand();
    }

    CopyMemory((PVOID)(p), p, MAX_AR_LENGHT);//Скопировать массив
}

void print() //вывод массива
{
    cout<<"Array: \n";
    int * p = pintAr;
    for(int i= 0; i<=19; i++)
    {
        cout<<p + " ";
    }
}

void ExitNicely(){
   
    UnmapViewOfFile(pintAr); // Убираем отображение файла
    CloseHandle(mapFileHandle);//Закрываем дескриптор отображения
    exit(0);//Выход из процесса
}

int main(int argc, _TCHAR* argv[])
{
   
   
    int res = 1;
    while( res ){//Пока не ввели 0
        cout<<"\nChoose action:\n"
            <<"1: Initialize\n"
            <<"2: Show array\n"
            <<"\n"
            <<"0: Exit\n\naction: ";
        cin>>res;

        if( res == 1 ){

            initialize();
            cout<<" ----- End -------\n\n";
            }
           
        else if(res == 2){
            print();
            }
       else if(res == 3){//Проверка прочитанных сообщений, посланных от id
           
        }else if(res == 4){//Очистка сообщений
           
        }else if(res == 5){//Печать всех сообщений
           
        }
    }
    ExitNicely();//Выходм, закрыв все дескрипторы0
    return 0;
}
76K
18 ноября 2011 года
SHDA
6 / / 26.10.2011
вы явно с паскаля перешли :)
после беглого просмотра:
вместо if(mapFileHandle = NULL) нужно if(mapFileHandle == NULL) и далее по тексту
вот так не совсем красиво for(int i= 0; i<=19; i++) если вы определили макрос о и работайте с ним for(int i= 0; i<MAX_AR_LENGHT; i++)
во здесь неверно CopyMemory((PVOID)(p), p, MAX_AR_LENGHT) зачем копировать в самого себя да и int весит 4 байта тогда уж так
CopyMemory((PVOID)(p), p, MAX_AR_LENGHT*sizeof(int))
да и где вызов randomize()?
76K
18 ноября 2011 года
MeGusta
5 / / 17.11.2011
Да я явно в запаре был. randomize вызвать забыл вот. Суть в том что со своей ошибкой я разобрался, она заключалась в неправильном использовании оператора вывода. Код теперь выглядит так:
Код:
#include <iostream>
#include <string>
#include <Windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <time.h>

#define BUF_SIZE 256*256 //Размер отображаемого файла

using namespace std;

int iar[20]; //объявление массива
int * piar = iar; //указатель на начало массива
HANDLE mapFileHandle; //Дескриптор отображаемого файла

void randomize(){

    srand((int)time(NULL));
    int * p = piar;
    for(int i = 0; i <= 19; i++)
    {
        *p = rand()*100/RAND_MAX;
        p++;
    }
    p = piar; //возврат указателя в начало массива
}

void print(){
    int * p = piar;
    cout<<"\n Elements: \n";
    for(int i = 0; i <= 19; i++)
    {
        cout<<*(p + i)<<" ";
    }
   
}

void ErrorExit(LPTSTR lpszFunction)
{
    // Получаем сообщение для кода последней ошибки

    LPTSTR lpMsgBuf;//Буфер сообщения ошибки
    LPTSTR lpDisplayBuf;//Буфер для всего сообщения аля "... failed with error: ..."
    DWORD dw = GetLastError();//Получаем код последней ошибки

    FormatMessage(//Получаем сообщение ошибки
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        lpMsgBuf,
        0, NULL );

   

    lpDisplayBuf = (LPTSTR)LocalAlloc(LMEM_ZEROINIT,
        (lstrlen(lpMsgBuf) + lstrlen(lpszFunction) + 40) * sizeof(TCHAR));  //Выделяем память под буфер

    // Форматируем сообщение
    StringCchPrintf(lpDisplayBuf,
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"),
        lpszFunction, dw, lpMsgBuf);

    //Показываем диалоговое окошко с сообщением
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

    LocalFree(lpMsgBuf);//Освобождаем память
    LocalFree(lpDisplayBuf);
    ExitProcess(dw); //Завершаем процесс
}

void initialize(){

    mapFileHandle = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BUF_SIZE, TEXT("Mapping")); //создаем отображение файла в памяти (в файле подкачки)
    if (mapFileHandle == NULL){
        ErrorExit(TEXT("CreateFileMapping error"));
    }

    //Отображаем файл на piar
   piar = (int*) MapViewOfFile(mapFileHandle, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, 0 );

   //Если ошибка, пишем сообщение и выходим
   if (piar == NULL){
    ErrorExit(TEXT("MapViewOfFile"));
   }
}

int main(int argc, char ** argv){
int res = 1;
    while( res ){//Пока не ввели 0
        cout<<"\nChoose action:\n"
            <<"1: Randomize\n"
            <<"2: Show unsorted array\n"
            <<"3: Send block\n"
            <<"4: Sort block\n"
            <<"5: Print sorted block\n"
            <<"\n"
            <<"0: Exit\n\naction: ";
        cin>>res;

        if( res == 1 ){//если выбрано действие 1
            initialize(); //инициализация файла в памяти
            randomize(); //заполнение массива в случайном порядке
            cout<<"\n \n Randomization complete \n";
        }else if(res == 2){
            print();
            cout<<"\n \n ----END---- \n";
        }else if(res == 3){
        }else if(res == 4){
           
        }else if(res == 5){
           
        }
    }
    //ExitNicely();//Выходм, закрыв все дескрипторы0
    return 0;
}

Массив заполняется и выводится на экран нормально. Ну мне так кажется во всяком случае. Нужно реализовать возможность блочной сортировки массива в другом процессе. Каждый новый процесс сортирует свою часть массива и отправляет главному процессу, который в свою очередь склеивает эти части обратно и сортирует уже весь массив. Есть идеи, как это сделать?
76K
18 ноября 2011 года
SHDA
6 / / 26.10.2011
может лучше создать дополнительные потоки, так будет проще, ну а если все-таки с дополнительными процессами, то во время создания процесса передавать в командной строке имя спроецируемого файла ну и размер области что надо отсортировать, после чего каждый процесс сортирует свою часть.
76K
18 ноября 2011 года
MeGusta
5 / / 17.11.2011
А можно какой-нибудь примерчик простенький? С передачей данных в процесс? Я так понял, это через CreateProcess надо делать?
76K
18 ноября 2011 года
SHDA
6 / / 26.10.2011
в общем я такими вещами не занимался, лучше читайте Рихтера, там всё есть, как знаю нужно создать процесс CreateProcess с атрибутами безопасности чтобы можно было наследовать дескрипторы других процессов, а в командной строке передаёте параметры откуда и сколько нужно сортировать, в основном процессе ждёте когда порождённые процессы закончат работу, ну и дальше по плану. В порожденном процессе проецируете файл под такимже именем что и в основном, должен подхватить, ну в общем экспериментируйте.
76K
18 ноября 2011 года
MeGusta
5 / / 17.11.2011
Спасибо, как раз начал. Закончу - выложу, что получилось.
76K
26 ноября 2011 года
MeGusta
5 / / 17.11.2011
Во, на экзамене приняли. Комментарии приветствуются.

Код:
#include <iostream>
#include <string>
#include <Windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <time.h>
#include <stdlib.h>

#define BUF_SIZE 256*256 //Размер отображаемого файла

using namespace std;

struct arrays{
    int iar[20]; //объявление массива
    int iar1[10]; //задание  массива для 1го блока
    int iar2[10]; //задание массива для 2го блока
};

arrays * piar; //указатель на начало массива
int st, en, id;
/*int * piar1 = iar1; //укзатель на начало 1го блока
int * piar2 = iar2; //указатель на начало 2го блока*/

HANDLE mapFileHandle; //Дескриптор отображаемого файла

void randomize(){

    srand((int)time(NULL));
    arrays * p = piar;
    for(int i = 0; i <= 19; i++)
    {
        p->iar = rand()*100/RAND_MAX;
        //p++;
    }
    p = piar; //возврат указателя в начало массива
}

void print(){
    arrays * p = piar;
    cout<<"\n Array: \n\n";
    for(int i = 0; i <= 19; i++)
    {
        cout<<p->iar<<" ";
    }
   
}

void ErrorExit(LPTSTR lpszFunction)
{
    // Получаем сообщение для кода последней ошибки

    LPTSTR lpMsgBuf;//Буфер сообщения ошибки
    LPTSTR lpDisplayBuf;//Буфер для всего сообщения аля "... failed with error: ..."
    DWORD dw = GetLastError();//Получаем код последней ошибки

    FormatMessage(//Получаем сообщение ошибки
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        lpMsgBuf,
        0, NULL );

   

    lpDisplayBuf = (LPTSTR)LocalAlloc(LMEM_ZEROINIT,
        (lstrlen(lpMsgBuf) + lstrlen(lpszFunction) + 40) * sizeof(TCHAR));  //Выделяем память под буфер

    // Форматируем сообщение
    StringCchPrintf(lpDisplayBuf,
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"),
        lpszFunction, dw, lpMsgBuf);

    //Показываем диалоговое окошко с сообщением
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

    LocalFree(lpMsgBuf);//Освобождаем память
    LocalFree(lpDisplayBuf);
    ExitProcess(dw); //Завершаем процесс
}

void initialize(){

    mapFileHandle = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BUF_SIZE, TEXT("Mapping")); //создаем отображение файла в памяти (в файле подкачки)
    if (mapFileHandle == NULL){
        ErrorExit(TEXT("CreateFileMapping error"));
    }

    //Отображаем файл на piar
   piar = (arrays*) MapViewOfFile(mapFileHandle, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, 0 );

   //Если ошибка, пишем сообщение и выходим
   if (piar == NULL){
    ErrorExit(TEXT("MapViewOfFile"));
   }
   id = id + 1; //идентификатор процесса
}

void bubbleSort(int start, int end){              //пузырьковая сортировка массива      
   
    arrays * p = piar;
    p = piar; //возврат указателя в начало
    int temp=0;
    int i = 0;
    int j = 0;
    int col = 0;

    col = (end - start) + 1;
    int a[20];


    for (i = (start-1); i <= (end - 1); i++) //выделение блока для сортировки во временный массив
    {
        a[j]=p->iar;
        j++;
    }
   

    cout<<"\nBlock received:\n\n";
    for (i = 0; i <= (col-1); i++) //показ блока для сортировки
    {
        cout<<a<<" ";
    }
   
    while(1){ //сортировка методом пузырька
        int k = 0;
        for(i = 0; i <= (col-1); i++){
            if(i < (col-1)){
            if(a>a[i+1]){
                temp=a;
                a=a[i+1];
                a[i+1]=temp;
                k++;
            }
            }
        }
        if(k==0) break;
    }

    for(i = 0; i <= (col-1); i++) //возврат значений из временного массива
    {
        if(id==1){
            p->iar=a;
        }else if(id==2){
            p->iar1 = a;
        }else{
            p->iar2 = a;
        }
    }

   
    cout<<"\nBlock sorted:\n\n";

    for (i = 0; i <= (col-1); i++) //показ отсортированного блока
    {
        if(id==1){
            cout<<p->iar<<" ";
        }else if(id==2){
            cout<<p->iar1<<" ";
        }else{
            cout<<p->iar2<<" ";
        }
    }
   
}

void ExitNicely(){
   
    UnmapViewOfFile(piar); // Убираем отображение файла на messages
    CloseHandle(mapFileHandle);//Закрываем дескриптор отображения
    exit(0);//Выход из процесса
}

void ShowBlocks(){

    arrays * p = piar;

    cout<<"\nBlock 1: \n";
    for(int i = 0; i <= 9; i++)
    {
        cout<<p->iar1<<" ";
    }
    cout<<"\nEnd of Block 1\n";

    cout<<"\nBlock 2: \n";
    for(int i = 0; i <= 9; i++)
    {
        cout<<p->iar2<<" ";
    }
    cout<<"\nEnd of Block 2\n";

}

void CombineBlocks(){ //передача блоков обратно в исходный массив

    arrays * p = piar;
    p = piar;

    for(int i = 0; i <= 9; i++){
        p->iar = p->iar1;
    }
    int j = 0;
    for(int i = 10; i<=19; i++){
        p->iar = p->iar2[j];
        j++;
    }
}


int main(int argc, char * argv[]){
int res = 1;
initialize(); //инициализация файла в памяти
if(argc < 2){//если процесс родительский(в командной строке не было передано параметров
    id = 1;
    st = 1;
    en = 20;
cout<<"Process: "<<id;
    while( res ){//Пока не ввели 0
        cout<<"\nChoose action:\n"
            <<"1: Randomize\n"
            <<"2: Show unsorted array\n"
            <<"3: Sort whole array\n"
            <<"4: Call processes\n"
            <<"5: Show blocks\n"
            <<"6: Combine and sort blocks\n"
            <<"\n"
            <<"0: Exit\n\naction: ";
        cin>>res;

        if( res == 1 ){//если выбрано действие 1
            randomize(); //заполнение массива в случайном порядке
            cout<<"\n \n Randomization complete \n";
        }else if(res == 2){//если выбрано действие 2
            print(); //вывод элементов массива на печать
            cout<<"\n \n ----END---- \n";
        }else if(res == 3){
            bubbleSort(st,en);
        }else if(res == 4){
            STARTUPINFO si = { sizeof(si) };
            PROCESS_INFORMATION pi;
            TCHAR szCommnandLine[] = TEXT("BLOCKSORT.exe 2 1 10");
            CreateProcess(NULL, szCommnandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
            TCHAR szCommnandLine2[] = TEXT("BLOCKSORT.exe 3 11 20");
            CreateProcess(NULL, szCommnandLine2, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
        }else if(res == 5){
            ShowBlocks();
        }else if(res == 6){
            CombineBlocks();
            bubbleSort(st,en);         
        }
    }
    ExitNicely();//Выходм, закрыв все дескрипторы
}
else { //если процесс дочерний

        id=atoi(argv[1]);
        st = atoi(argv[2]);
        en = atoi(argv[3]);
        cout<<"Process: "<<id<<" Block: "<<st<<"-"<<en;
        if(id == 2){
        bubbleSort(st,en);
        }
        else bubbleSort(st,en);
        cout<<"\n Press ENTER \n";
        cin.get();
}
    return 0;
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог