Reputation: 147
I try to write a c++ program of file manager . I wrote a "CommandEngine" class, which handles commands, a "Command" class, which is abstract class, containing "execute" function, etc. I try to create a file on specified path (without giving response at that level of development of my program). The code that I wrote compiled successfully, but when I try to execute it, I have got an error
" Unhandled exception at 0x0022DC96 in FileManager2.exe: 0xC0000005: Access violation reading address 0x00000014."
I will be very grateful for any help. Thanks to everybody.
// 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
Upvotes: 0
Views: 807
Reputation: 23001
You have a number of unintialised objects that are likely to cause your code to crash.
First you don't initialise input in the CommandEngine class so when you call input->ReadInput()
you are using an uninitialised pointer.
Second, as Casey as already said, you don't initialise the CreateFileCl object that you insert in the CommandHandlers list, so when you try and execute the command that is going to fail too.
You can fix this by updating your CommandEngine constructor to initialise those two objects.
CommandEngine::CommandEngine()
{
input = new Input();
CreateFileCl * Cr = new CreateFileCl();
string s = "create";
CommandHandlers.insert(pair<string, Command *>(s, Cr));
}
Note that you will also need to delete the input object in the CommandEngine destructor.
CommandEngine::~CommandEngine()
{
delete input;
}
Freeing up the memory for the CreateFileCl object is more complicated - assumedly there could be multiple command handlers, so you need to go through the list and delete all of them. But really you shouldn't be allocating memory like this. Ideally you should be using smart pointers that take care of the memory management for you.
Upvotes: 1
Reputation: 42574
In the CommandEngine
constructor, you are storing an uninitialized CreateFileCl
pointer inside the CommandHandlers
map. When you later try to call Command::Execute
through that pointer, terrible things (undefined behavior) happen.
Upvotes: 1