Victor
Victor

Reputation: 147

c++ program of file manager compiles, but does not works

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

Answers (2)

James Holderness
James Holderness

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

Casey
Casey

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

Related Questions