So, I've got the following Command Pattern implementation, which is contained within a std::map<CString, IWrite*> commandMap:
class IWrite
{
protected:
CStdioFile* fileWriter;
public:
IWrite(CStdioFile* _fileWriter)
: fileWriter(_fileWriter)
{
}
virtual ~IWrite()
{
}
virtual BOOL exec() = 0;
};
class FloatWrite : public IWrite
{
private:
float input;
public:
FloatWrite(CStdioFile* _fileWriter, float _input)
: IWrite(_fileWriter), input(_input)
{
}
BOOL exec()
{
CString fieldvalue;
fieldvalue.Format("%f", input);
fileWriter->WriteString(fieldvalue);
return TRUE;
}
};
The issue I'm having is that my static analysis tool complains that fileWriter is not freed or zeroed in the destructor of IWrite. However, by adding a delete fileWriter in the destructor, I get a memory access error when I delete the Command Pattern object in the map before calling std::map.clear() as below:
// free map memory
for ( std::map<CString, IWrite*>::iterator mapItr = commandMap.begin();
mapItr != commandMap.end();
++mapItr)
{
delete mapItr->second;
}
commandMap.clear();
Am I approaching memory management incorrectly here? I have not done much work with STL maps, so I'm not familiar with an idiomatic approach.
EDIT: How I add elements to the map:
void FooClass::initCommandMap(const MSG_DATA_STRUCT * msgdata)
{
// Write a float, foo
commandMap[_T("foo")] = new FloatWrite(&fileWriter, msgdata->foo);
// Write an unsigned int, bar
commandMap[_T("bar")] = new UIntWrite(&fileWriter, msgdata->bar);
// etc...
}
This is called each time the user chooses to write out the data, so the fileWriter object used by the various exec()'s is current with the file selected by the user.
Note that CStdioFile fileWriter is a member variable of FooClass.
Why do you keep a pointer to fileWriter? From what I see, your Command object assumes that a writer should exist before the command can be used. It also shouldn't try to manage the writer object, since it can be shared by multiple command objects.
Try keeping a reference instead.
class IWrite
{
protected:
CStdioFile &fileWriter;
public:
IWrite(CStdioFile &_fileWriter)
: fileWriter(_fileWriter)
{
}
virtual ~IWrite()
{
}
virtual BOOL exec() = 0;
};
Related
I have a memory corruption in my program. The driver_s2lp::_conf.rxtx object gets corrupted, after a while (involving some new and delete) in my program.
class driver_s2lp
{
public:
struct conf
{
std::function<std::vector<uint8_t>(std::vector<uint8_t> &data, size_t len)> rxtx;
//there are other variables here
};
driver_s2lp::driver_s2lp(conf config)
{
_conf = config;
}
private:
conf _conf;
};
class s2lp_custom_ikm : private driver_s2lp
{
struct conf
{
std::function<std::vector<uint8_t>(std::vector<uint8_t> &data, size_t len)> rxtx;
//there are other variables here
};
/* can I safely copy the std::function like this ? */
s2lp_custom_ikm(conf configuration) : driver_s2lp([configuration]() {
struct driver_s2lp::conf driver_conf;
driver_conf.rxtx = configuration.rxtx;
// other copies here
return driver_conf;
}())
{
this->configuration = configuration;
}
void do_something()
{
// it seems that driver_s2lp::_conf.rxtx can be broken here
}
};
int main()
{
s2lp_custom_ikm::conf s2lp_config;
s2lp_config.debug = [](std::string s) { printf("%s",s.c_str()); };
//other std::functions here
s2lp = new s2lp_custom_ikm(s2lp_config);
s2lp->do_something()
while(1){};
}
I wonder if there is something wrong with copying std::function as I do in the constructor of the s2lp_custom_ikm class?
I'm not sure it is relevant but it is the m_invoker which gets corrupted in the std::function object when I add a watchpoint in the debugger.
The problem may be somewhere else but I want to be sure the copy is not the source of the problem.
I wonder if there is something wrong with copying std::function as I do in the constructor of the s2lp_custom_ikm class?
No.
The std::function copies in your constructor (both the initialiser and the body) are safe.
The program snippet shown does not contain a bug capable of the symptoms you report.
For the life of me I cannot understand at all why this program is getting a segmentation error. The issue is that it retrieves an object within the vector container uses a function within the menu class using the get_command() and for some reason after testing the main function line by line this one results in a segmentation fault:
menu->get_command()->execute();
I have tried changing the syntax to create a new command object that stores the returned object from get_command() and changed the index between 0 and -1 and still nothing fixes the error. I have spent at least a couple of hours trying to figure out why but I cannot seem to find a solution.
class Base {
public:
/* Constructors */
Base() { };
/* Pure Virtual Functions */
virtual double evaluate() = 0;
virtual std::string stringify() = 0;
};
class op : public Base
{
public:
op() { };
op(double op1) { operand = op1; }
double evaluate() { return operand; }
string stringify() {
string value = to_string(operand);
return value;
}
private:
double operand;
};
class Command {
protected:
Base* root;
public:
Command() { this->root = nullptr; }
double execute() { return root->evaluate(); }
std::string stringify() { return root->stringify(); }
Base* get_root() { return root; }
};
class Menu {
private:
int history_index; // Indexes which command was last executed, accounting for undo and redo functions
std::vector<Command*> history; // Holds all the commands that have been executed until now
public:
Menu() {
// Constructor which initializes the internal members
history_index = -1;
}
std::string execute() {
// Returns the string converted evaluation of the current command
return to_string(history[history_index - 1]->execute());
}
std::string stringify() {
// Returns the stringified version of the current command
return history[history_index]->stringify();
}
bool initialized() {
// Returns if the history has an InitialCommand, which is necessary to start the calculation
if (history[history_index] != nullptr)
return true;
else
return false;
}
void add_command(Command* cmd) {
// Adds a command to the history (does not execute it), this may require removal of some other commands depending on where history_index is
history.push_back(cmd);
history_index++;
}
Command* get_command() {
// Returns the command that the history_index is currently referring to
return history[history_index];
}
void undo() {
// Move back one command (does not execute it) if there is a command to undo
history_index--;
}
void redo() {
// Moves forward one command (does not execute it) if there is a command to redo
history_index++;
}
};
class InitialCommand : public Command {
protected:
Base* root;
public:
InitialCommand(Base* b) { this->root = b; }
double execute() { return root->evaluate(); }
std::string stringify() { return root->stringify(); }
Base* get_root() { return root; }
};
void main()
{
Menu* menu = new Menu();
InitialCommand* temp = new InitialCommand(new op(7));
menu->add_command(temp);
EXPECT_EQ(menu->get_command()->execute(), 7);
system("PAUSE");
}
You're not doing inheritance right, as you are duplicating fields between Command and InitialCommand that lead to the error.
Both command classes have a Base *root member, and non-virtual execute methods. When you construct a new InitialCommand object, the InitialCommand::root object points at the op that was created for it, while Command::root remains NULL because of the default constructor for Command. Then, when you call menu->get_command(), it will call Command::execute because execute is non-virtual and menu is a Command *. Command::execute will then dereference a NULL root, causing your segmentation error.
Remove the Base *root member from InitialCommand, and pass the parameter to a constructor in Command. You probably want to make some methods like execute virtual.
The problem is that your Command and InitialCommand both have root variable.
InitialCommand* temp = new InitialCommand(new op(7)); will according to your constructor set InitialCommand::root. So Command::root remains uninitialized. Then Menu holds std::vector<Command*>, so InitialCommand* is implicitly converted to Command*.
At alst calling Command::execute will indeed call Command:execute because the method is not virtual. So, the uninitialized Command::root is used -> seg. fault.
Please don't use new. Use smart pointers - std::unique_ptr should be the default way to manage dynamic memory.
That said, your code seems too Java/C# like. This is C++, use value semantics if you can. There's no reason for Menu* menu = new Menu();. Menu menu; is simpler and works the same in your case. Here's a code I would've written
#include <memory>
#include <vector>
#include <string>
using namespace std;//Not a good practice and definitely a big no in header files.
class Base {
public:
/* Constructors */
Base() { };
/* Pure Virtual Functions */
virtual double evaluate() = 0;
virtual std::string stringify() = 0;
};
class op : public Base
{
public:
op() { };
op(double op1) { operand = op1; }
double evaluate() { return operand; }
string stringify() {
string value = to_string(operand);
return value;
}
private:
double operand;
};
class Command {
protected:
std::unique_ptr<Base> root;
public:
Command(std::unique_ptr<Base>&& root):root(std::move(root)) { }
//Be const-correct
double execute() const { return root->evaluate(); }
std::string stringify() const { return root->stringify(); }
Base* get_root() const { return root.get(); }
};
class Menu {
private:
int history_index; // Indexes which command was last executed, accounting for undo and redo functions
std::vector<std::unique_ptr<Command>> history; // Holds all the commands that have been executed until now
public:
Menu() {
// Constructor which initializes the internal members
history_index = -1;
}
std::string execute() const{
// Returns the string converted evaluation of the current command
return to_string(history[history_index - 1]->execute());
}
std::string stringify() const{
// Returns the stringified version of the current command
return history[history_index]->stringify();
}
bool initialized() const{
// Returns if the history has an InitialCommand, which is necessary to start the calculation
if (history[history_index] != nullptr)
return true;
else
return false;
}
void add_command(std::unique_ptr<Command>&& cmd) {
// Adds a command to the history (does not execute it), this may require removal of some other commands depending on where history_index is
history.emplace_back(std::move(cmd));
history_index++;
}
Command* get_command() const {
// Returns the command that the history_index is currently referring to
return history[history_index].get();
}
void undo() {
// Move back one command (does not execute it) if there is a command to undo
history_index--;
}
void redo() {
// Moves forward one command (does not execute it) if there is a command to redo
history_index++;
}
};
class InitialCommand : public Command {
protected:
public:
InitialCommand(std::unique_ptr<Base>&& b): Command(std::move(b)){}
};
// There's no such thing as void main
int main()
{
Menu menu;
auto temp = std::make_unique<InitialCommand>(std::make_unique<op>(7));
menu.add_command(std::move(temp));
//EXPECT_EQ(menu.get_command()->execute(), 7);
system("PAUSE");
}
It uses move semantics which used to not be a beginners concept, but it's such integral part of modern C++ that every C++ programmer must learn it sooner rather than later.
I work on a project made with cocos2d-x framework (c++).
In my Player class, I have to manage the animations.
Iinitially I had this code that worked without any problem:
First, the animation object is a cocos2d Class cocos2d::Animation. Just remember that this object contains a cocos2d::Vector<AnimationFrame*> _frames; member.
Doc: http://www.cocos2d-x.org/reference/native-cpp/V3.5/d3/dc5/classcocos2d_1_1_animation.html#a0fdc0be158df7e09d04644be353db056
class Player : public cocos2d::Sprite {
private:
cocos2d::Map<std::string, cocos2d::Animation*> animations;
cocos2d::Vector<cocos2d::SpriteFrame*> getAnimation(const char *format, int frameStart, int count);
void update(float delta) override;
bool init() override;
public:
static Player* create();
bool init() override;
//...
};
And the implementation side:
bool Player::init() {
//...
animations.insert("idleN", Animation::createWithSpriteFrames(getAnimation("%04d", 207, 9), 0.1));
//...
}
Vector<SpriteFrame*> Player::getAnimation(const char *format, int frameStart, int count) {
auto spriteCache = SpriteFrameCache::getInstance();
Vector<SpriteFrame*> animFrames;
char str[100] = {0};
for (int i = 1; i <= count; i++)
{
sprintf(str, format, frameStart);
log("%s", str);
animFrames.pushBack(spriteCache->getSpriteFrameByName(str));
frameStart++;
}
return animFrames;
}
//later in the code execution
void Player::manageIdle() {
auto idleAnim = Animate::create(animations[0].anim);
runAction(idleAnim);
}
You can see each Animation is contained in cocos2d::Map<std::string, cocos2d::Animation*> and as I say before, this code worked perfectly, no error.
But I needed some more informations in addition to the name and the object itself so I decided to use a structure to store all infos for each animation. And I replaced the cocos2d::Map<std::string, cocos2d::Animation*> by std::vector<animData> with animData as structure. I refactored the code like so:
class Player : public cocos2d::Sprite {
public:
typedef struct animation {
std::string name;
cocos2d::Animation* anim;
//all others info needed, not relevant here, (just several enum type variables)
} animData;
private:
std::vector<animData > animations; //the new container
//rest of code stay unchanged
};
The changes in the implementation side:
bool Player::init() {
//...
animations.push_back({"idleN", Animation::createWithSpriteFrames(getAnimation("%04d", 207, 9), 0.1)});
//no problem here...
}
But now, when I try to create a new anim with a animation saved in my container (vector) I get a SegV on this line:
void Player::manageIdle() {
auto idleAnim = Animate::create(animations[0].anim); //SegV here, in Animate::create() funct
runAction(idleAnim);
}
After search, I find that each structure member anim which is type of cocos2d::Animation*, now conatains a empty cocos2d::Vector<AnimationFrame*> _frames; and there is the problem !
It’s as if they lose the cocos2d::Vector<AnimationFrame*> ref or something like that.
So my question is why cocos2d::Vector<AnimationFrame*> become empty with my refactored code and not whith the previous one ?
I found this with test like that:
auto test = animList[0].anim->getFrames();
if (test.empty()) {
log("empty"); //The test output empty
}
Debugguer screen in the end of the init() funct:
Debugguer screen in Player::manageIdle() funct:
Edit: when I add animations.back().anim->retain(); right after the line to add an element in the vector, it solves the problem !
animations.push_back({"idleN", Animation::createWithSpriteFrames(getAnimation("%04d", 207, 9), 0.1)});
animations.back().anim->retain();
Because cocos2d::Animation* inherit from cocos2d::Ref, it is an auto-release object. When used inside a cocos2d container like cocos2d::Map or cocos2d::Vector, it is auto managed by the container itself. But I use a std::vector so I lose the ref I think. Something like that.
Now I need to find a way to get rid of this additional line of code because this multiple by twice my number of line here !
So new question here: How I can get rid of the fact I have to call animations.back().anim->retain(); each time I add a new element in my vector ?
You might create a wrapper around Ref, which "retains" ownership, and store this wrapper instead, sort of a std::unique_ptr e.g.
template<typename T> class RefOwner {
public:
RefOwner(T *t) : ref(t) {
ref->retain();
}
~RefOwner() {
ref->release();
}
T *operator->() { return ref; }
private:
T *ref;
};
and then use it as
struct animData {
std::string name;
RefOwner<cocos2d::Animation> anim;
//all others info needed, not relevant here, (just several enum type variables)
};
Disclaimer: I have no experience with cocos2d-x, just looked at Animation and Ref
I'm trying to create a class wrapping fopen() / fclose() / f* methods. I want to use this method for other purposes, that's why I don't want to use smart pointers.
The problem is I don't know when to call fclose() or other 'end of life' functions. Destructor could be called but in the meantime FILE * was copied to another object for example by copy constructor.
I tried writing 'Reference Counter' class (that will be base class of all classes) but unfortunately I'm not able to call pure virtual methods from constructor / destructor.
This is what I've tried:
class ReferenceCounter
{
public:
ReferenceCounter()
{
ReferenceCount = new unsigned int(0);
AddRef();
}
ReferenceCounter(const ReferenceCounter & CopyFrom)
{
ReferenceCount = CopyFrom.ReferenceCount;
AddRef();
}
ReferenceCounter & operator = (const ReferenceCounter & AssignFrom)
{
RemoveRef();
ReferenceCount = AssignFrom.ReferenceCount;
AddRef();
return *this;
}
~ReferenceCounter()
{
RemoveRef();
}
virtual void OnInit() = 0;
virtual void OnDestruct() = 0;
private:
unsigned int * ReferenceCount;
void AddRef()
{
if(++*ReferenceCount == 1)
OnInit();
}
void RemoveRef()
{
if(--*ReferenceCount == 0)
{
OnDestruct();
delete ReferenceCount;
}
}
};
Maybe there is a way to 'overwrite' or 'overlay' one class over another?
Example:
class File
{
public:
File(std::string FileName)
{
F = fopen(FileName.c_str(), ...);
}
~File()
{
fclose(F);
}
private:
FILE * F;
};
int main()
{
File File1("a.txt");
auto File2 = File1;
//SegFault = fclose called twice for File1 and File2
}
There are two solutions here, which work in tandem.
First, don't allow assignment or copying of your "file handle" class.1
class File
{
// C++11 solution: use =delete
public:
File(File & const) = delete;
File & operator=(File & const) = delete;
// C++ < 11 solution: make them private and *don't implement them*:
private:
File(File & const);
File & operator=(File & const);
};
Second, consider only passing references to a single File object. (The compiler won't let you copy File objects anymore, so if you are doing this by accident you will get a compiler error -- this is good, because it will help you identify areas you need to fix.)
If it's too difficult to establish a single point of ownership, then consider instead passing instances using std::shared_ptr<File> which does exactly the kind of reference counting you are trying to implement -- the File will be deleted (and therefore its destructor called) when the last std::shared_ptr is itself destructed.
auto file = std::make_shared(new File{"a.txt"});
auto file2 = file;
// file.use_count() and file2.use_count() are now both 2.
//
// When file2 is destructed this will drop to 1; when file is destructed this will
// drop to 0, and the File object will be deleted.
1 Note that you could probably implement copying using dup(), though semantics for assignment may be a bit trickier -- should assignment close the existing handle and dup() the handle being assigned? If you do implement dup() functionality I would be more inclined to make it a member function instead so that its usage is explicit instead of happening automatically when you may not intend it to.
You can use a shared pointer with fclose as deleter:
#include <cstdio>
#include <memory>
#include <stdexcept>
class File
{
private:
typedef std::shared_ptr<FILE> shared_file;
public:
// You might consider const char*
File(const std::string& FileName, const std::string& Mode)
: F(std::fopen(FileName.c_str(), Mode.c_str()), fclose)
{
if( ! F.get()) {
throw std::runtime_error("File Open Failure");
}
}
private:
shared_file F;
};
int main()
{
File File1("/tmp/test.txt", "r");
auto File2 = File1;
}
class item
{
int i;
public:
item(int no) {
}
};
I want to check the constructor parameter. If it is found to hold a negative value, then object creation should be stopped.
Exceptions can not be used here as the targeted system does not support exceptions.
There is no way to stop the creation of an object without throwing. The best you can do is set an "invalid parameter" flag that you have to check afterwards, and if true discard the object without using it.
With the requirements you have, it would probably be better to use a factory method to create the objects -- this way, you can make the checks before calling the constructor:
class item
{
int i;
public:
static item* create(int no) {
if (no < 0) {
return 0;
}
return new item(no);
}
private:
item(int no) {
}
};
You could use this like
item* myItem = item::create(-5);
if(!myItem) {
// failed
}
However, this forces you to allocate all item instances on the heap.
Exceptions are the way designated by the standard to perform this task; there's no other way to abort completely the object creation.
On the other hand, you can give your class some "state" member that specifies that the class was not correctly constructed and check it at every method call (a bit like how iostream classes work).
class item
{
int i;
bool validState;
public:
item(int no) : validState(true)
{
if(/* no is invalid */)
{
validState = false;
return;
}
/* ... */
}
bool ValidState() { return validState; }
SomeType DoSomething()
{
if(!ValidState())
{
// do nothing/report the error to the caller
}
// ...
}
}
IMO it's cumbersome, but if you don't have exceptions and want to create objects via a public constructor there's nothing much better than this.
You cannot stop object construction mid-way, without throwing an exception.
That said, you may outright prevent construction of item objects which fail a precondition, by moving the precondition and object-creation responsibilities to a separate factory function, and making the constructors private (to disallow all other ways to construct the object):
class item {
int i;
public:
static item* create( int no )
{
return no < 0 ? NULL : new item( no );
}
private:
item() { ... }
item( int no ) { ... }
};
Three options.
Use a flag in your class to track full construction - but you'll have to test that in each method.
Make item a wrapper, such that the internals are held in a class that is constructed if the arguments are good, but in all the methods, you'll have to test the internals - so no different to 1 anyway.
Use a factory to return a smart pointer if the arguments are good.
My preference in this scenario is the last one.
Put the object into an error state (use a boolean) and then all methods should return an error.
ie
class Item
{
int i;
bool errorState;
public:
Item(int n) : i(n) {
errorState = i < 0;
}
bool method()
{
if (errorState) return false;
..... do stuff here
return true;
}
}
You can do it at compile time with necessary warning flags ON (e.g. -Wall in gcc).
class item
{
public:
item(unsigned int no) {} // item takes only +ve value
};
Compiler will warn you if a -ve value is passed.