C++ программа файлового менеджера компилируется, но не работает
Я пытаюсь написать на С ++ программу файлового менеджера. Я написал класс "CommandEngine", который обрабатывает команды, класс "Command", который является абстрактным классом, содержит функцию "execute" и т. Д. Я пытаюсь создать файл по указанному пути (без ответа на этом уровне разработки). моя программа). Код, который я написал, успешно скомпилирован, но когда я пытаюсь его выполнить, появляется ошибка
"Необработанное исключение в 0x0022DC96 в FileManager2.exe: 0xC0000005: адрес чтения нарушения доступа 0x00000014."
Буду очень признателен за любую помощь. Спасибо всем.
// FileManager.cpp
#include <stdio.h>
#include <tchar.h>
#include "CommandEngine.h"
#include "Command.h"
#include "CreateFile.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
CommandEngine C;
C.CommandHandler();
return 0;
}
// CommandEngine.h
#ifndef COMMANDENGINE_H
#define COMMANDENGINE_H
#include "Command.h"
#include "CreateFile.h"
#include "Input.h"
#include <map>
#include <string>
using namespace std;
class CommandEngine
{
public:
typedef map< string , Command * > MapOfHandlers;
MapOfHandlers CommandHandlers;
Input * input;
Command * GetCommand(const string & commandName)
{
map< string , Command * >::iterator iter;
iter = CommandHandlers.find(commandName);
return iter->second;
};
void CommandHandler();
CommandEngine();
~CommandEngine();
};
CommandEngine::CommandEngine()
{
CreateFileCl * Cr;
string s = "create";
CommandHandlers.insert(pair<string, Command *>(s, Cr));
}
CommandEngine::~CommandEngine()
{
}
void CommandEngine::CommandHandler()
{
Response response;
Command * command = GetCommand( ( input->ReadInput() ) -> GetCommandName());
command->Execute(input, &response);
WriteResponse(&response);
}
#endif // COMMANDENGINE_H
//Command.h
#ifndef COMMAND_H
#define COMMAND_H
#include "Input.h"
#include "Response.h"
using namespace std;
class Command
{ public:
virtual void Execute(Input * input, Response * response ) = 0;
};
#endif // Command_H
/*void StrToChar(string s)
{
string s;
string writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0'; // don't forget the terminating 0
// don't forget to free the string after finished using it
delete[] writable;
} */
////////////////////////////////////////////////////////////////////////////////////////////////////
// Input.h
#ifndef INPUT_H
#define INPUT_H
#include <string>
#include <iostream>
using namespace std;
class Input
{
public:
string CommandName;
string FileName;
string DestinationPath; // For " copy " command
Input * ReadInput();
const string GetCommandName()// can be no useful
{
return CommandName;
};
Input();
~Input();
};
Input::Input()
{
CommandName = FileName = DestinationPath = " ";
}
Input::~Input()
{
}
Input * Input::ReadInput()
{
cout<<"Enter command";
getline(cin,CommandName);
getline(cin, FileName);
getline(cin,DestinationPath );
return this;
}
#endif // INPUT_H
// CreateFile.h
#ifndef CREATEFILE_H
#define CREATEFILE_H
#include <windows.h>
#include "Command.h"
using namespace std;
class CreateFileCl : public Command
{
public:
virtual void Execute(Input * input, Response * response );
};
void CreateFileCl::Execute(Input * input, Response * response )
{
/*const string text = (input->FileName).c_str();
wchar_t wtext[20];
mbstowcs(wtext, text, strlen(text)+1);//Plus null
LPWSTR ptr = wtext; */
CreateFileA( (input->FileName).c_str(), 0, 0, 0, 0, 0, 0);
}
#endif // CREATEFILE_H
2 ответа
У вас есть несколько нереализованных объектов, которые могут вызвать сбой вашего кода.
Во-первых, вы не инициализируете ввод в классе CommandEngine, поэтому при вызове input->ReadInput()
Вы используете неинициализированный указатель.
Во-вторых, как уже сказал Кейси, вы не инициализируете объект CreateFileCl, который вы вставляете в список CommandHandlers, поэтому при попытке выполнить команду, которая тоже не удастся выполнить.
Вы можете исправить это, обновив конструктор CommandEngine для инициализации этих двух объектов.
CommandEngine::CommandEngine()
{
input = new Input();
CreateFileCl * Cr = new CreateFileCl();
string s = "create";
CommandHandlers.insert(pair<string, Command *>(s, Cr));
}
Обратите внимание, что вам также необходимо удалить входной объект в деструкторе CommandEngine.
CommandEngine::~CommandEngine()
{
delete input;
}
Освободить память для объекта CreateFileCl более сложно - предположительно может быть несколько обработчиков команд, поэтому вам нужно просмотреть список и удалить их все. Но на самом деле вы не должны распределять память таким образом. В идеале вы должны использовать умные указатели, которые позаботятся об управлении памятью за вас.
В CommandEngine
конструктор, вы храните неинициализированный CreateFileCl
указатель внутри CommandHandlers
карта. Когда вы позже попытаетесь позвонить Command::Execute
через этот указатель происходят ужасные вещи (неопределенное поведение).