I got a unhandled exception error at runtime when using the following C++ code, you can follow the error with debug using Visual Studio. Why will this exception happen, can you explain it?
First I define a class with a menber variable "_name"
void insert_Fenster(int pos,wstring name);
wstring get_Fenster_name(int pos);
class Fenster
{
public:
Fenster(wstring name)
:_name(name)
{}
void reload()
{
_name;
insert_Fenster(1,L"temp");
wstring tmp = get_Fenster_name(1);
_name = tmp; //ERROR!!!
}
wstring get_name()
{
return _name;
}
private:
wstring _name;
};
Second I define a class to hold a map of the class
class FensterManager
{
public:
bool has(int pos)
{
if (_mapFenster.find(pos)!=_mapFenster.end())
return true;
else
return false;
}
void insert(int pos,wstring name)
{
if (has(pos))
{
_mapFenster.erase(pos);
}
_mapFenster.insert(make_pair(pos,Fenster(name)));
}
Fenster& get_Fenster(int pos)
{
return _mapFenster.at(pos);
}
private:
static map<int,Fenster> _mapFenster;
};
And some util functions
void insert_Fenster(int pos,wstring name)
{
FensterManager fm;
fm.insert(pos,name);
}
void reload_Fenster(int pos)
{
FensterManager fm;
if (fm.has(pos))
fm.get_Fenster(pos).reload();
}
wstring get_Fenster_name(int pos)
{
wstring name;
FensterManager fm;
if (fm.has(pos))
name = fm.get_Fenster(pos).get_name();
return name;
}
//Init of static member before main function
map<int,Fenster> FensterManager::_mapFenster;
that is the main function
void main()
{
insert_Fenster(1,L"xyz");
reload_Fenster(1);
}
The exception happen at "reload" function in class "Fenster".
With error message:
Unhandled exception at 0x005cca34 (msvcr100d.dll) in Regular_Expression.exe: 0xC0000005: Access violation writing location 0xfeeefeee.
When you call reload_Fenster(1);, it will call Fenster::reload. In that function you call insert_Fenster(1,L"temp");. FensterManager::insert will first erase position 1 from the map. So when you return to Fenster::reload, the instance has been deleted. As soon as you try to access _name, you try to access memory which has been deleted.
edit:
To clarify; this function call:
fm.get_Fenster(pos).reload();
will first call fm.get_Fenster(pos) and then call reload() on the result. If fm.get_Fenster(pos) changes in the reload() function, execution will not move the new Fenster, but the old one will keep executing. Even if you delete the old Fenster.
You should make sure not to delete an instance if you are still running functions inside it. It will crash the application as soon as you try to access members, because they are stored in memory which has been deleted.
looks like something inside void insert_Fenster(int pos,wstring name); - look further up the call stack and you'll see which part of your code is calling into the runtime dll. That'll be the error.
Can you please provide more information regarding the unhandled exception.
There is one obvious mistake in the above code. The insert_Fenster is inserting into a FensterManager instance and the reload_Fenster is trying to reload from a different instance of the FensterManager which is wrong.
void main()
{
FensterManager fm;
insert_Fenster(fm, 1,L"xyz");
reload_Fenster(fm, 1);
}
The insert and reload method should be updated as follows:
void insert_Fenster(FensterManager &fm, int pos,wstring name)
{
fm.insert(pos,name);
}
void reload_Fenster(FensterManager &fm, int pos)
{
if (fm.has(pos))
fm.get_Fenster(pos).reload();
}
Related
I have CPrinterDlg class which contains
// CPrinterDlg.h
public:
CEdit m_editRxFreq;
void print_SignalData(unsigned int freq, float wvlen);
// CPrinterDlg.cpp
void CPrinterDlg::print_SignalData(unsigned int freq, float wvlen)
{
m_editRxFreq.SetWindowTextW(L"ddd");
}
In order to access that function I did in MainFrm like this:
public:
CPrinterDlg m_PrinterDlg;
CPrinterDlg& getPrinterDlg() { return m_PrinterDlg; }
And from where I am calling print_SignalData(...) is CSMsg``` class
void CSockMsg::Send_SignalData(unsigned char* msg)
{
//..
CMainFrame* pMain = (CMainFrame*)AfxGetApp()->GetMainWnd();
pMain->getPrinterDlg().print_SignalData(freq, wvlen);
}
When I call print_SignalData(...) from one of the CPrinter function directly, it's working well. But, When I try to call it from CSMsg::Send_SignalData(unsigned char* msg) it's giving me Debug Assertion(...MFC\winocc.cpp Line: 242) from this point:m_editRxFreq.SetWindowTextW(L"ddd");.
And I see that m_editRxFreq is NULL.
So, how do you think why m_editRxFreq is getting be NULL? and how can I solve this problem??
Solved!
I was doing
public:
CPrinterDlg m_PrinterDlg;
CPrinterDlg& getPrinterDlg() { return m_PrinterDlg; }
in CMainFrm.h,
and actually Creating and Showing that dlg
CPrinterDlg dlg;
dlg.Create(...);
dlg.ShowWindow(...);
was in CxxView::OnInitialUpdate().
That's why when I called pMain->getPrinterDlg().print_SignalData(freq, wvlen); it was giving me NULL;
So in order to solve it,
I created CPrinterDlg dlg.Create(...) in CMainFrm class but not in CxxxView class.
Guys I can't seem to do simple modification of a container object member stored in a vector. This member is an object itself. Both the container and its member are allocated on the stack. I think it is trying to deallocate a stack variable of the original name of the device when assigning a new one.
Please give me a clue on how to fix this while keeping variables allocated on the stack.
class Device{
public:
Device(string name):m_name(name)
{}
string getName(){
return m_name;
}
string setName(string newName){
m_name = newName;
}
private:
string m_name;
};
Then there is a Server that contains Devices:
class Server
{
public:
Device & getDevice(int i)
{
return devices.at(i);
}
void addDevice(Device && dev)
{
devices.push_back(dev);
}
private:
vector<Device> devices;
};
Here is how I test:
int main()
{
Server s{};
s.addDevice(Device{"ONE"});
s.addDevice(Device{"TWO"});
s.addDevice(Device{"THREE"});
cout<<s.getDevice(0).getName()<<endl;
s.getDevice(0).setName("XXX");
cout<<s.getDevice(0).getName()<<endl;
return 0;
}
What I am getting out is :
ONE
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000000617c20 ***
Aborted (core dumped)
You need to fix your setName method, is not returning anything and is marked to return a string.
string setName(string newName)
{
m_name = newName;
return m_name; //this is missing in the original code
}
I am currently benchmarking a program on a Linux system with Valgrind.
I have this strange cache miss with the getter method const int GetID() const,
but I can't really explain where it came from. Does anyone have any idea what's causing this problem?
I thought it might be caused by the constant keyword at the end, but it hasn't changed.
The cache miss occurs in the L1 during the read operation. I have added a screenshot below the code snippet.
class GameObject
{
friend class GameManager;
private:
int id;
GameObject();
static int CreateID() { return /* do some id stuff in here */}
...
public:
~GameObject();
const int GetID() const { return id; }
...
};
KCachegrind Screenshot:
UPDATE:
These are methods of the GameManager class that call the const int GetID() const method. It is called when a GameObject must be destroyed or returned to a specific point. The GameManager contains a vector of all GameObjects, they are created when the application starts, after which the vector does not change at all.
After they are created, the attached components call the GameObject* GetGameObject(int const _gameObjectId) method once to retrieve all required components. So I guess the GameObjects should already be in the cache or did I miss a point?
Maybe the call is so strong that it creates more cache misses at the beginning of the program than the rest of the application at runtime?
void GameManager::DestroyGameObject(const int _id)
{
for (auto it = gameObjects.begin(); it != gameObjects.end(); it++)
{
if (it->GetID() == _id)
{
gameObjects.erase(it);
return;
}
}
}
GameObject* GameManager::GetGameObject(const int _gameObjectId)
{
for (int i = 0; i < gameObjects.size(); i++)
{
if (gameObjects[i].GetID() == _gameObjectId)
{
return &gameObjects[i];
}
}
return nullptr;
}
How do I create a class setter member function that uses const reference as its parameters? I wrote the definition of the setter of how I thought it should be, but upon running it breaks and returns a "read access violation" exception.
//==== Start of Main.cpp ====
int main()
{
std::string temp="test";
NodeData thingy;
thingy.setname(temp);
return 0;
}
//==== End of Main.cpp ====
//==== Start of NodeData.hpp====
class NodeData
{
public:
void setname(const std::string &newName);
private:
std::string *mpName;
};
//==== End of NodeData.hpp ====
//==== Start of NodeData.cpp====
void NodeData::setname(const std::string &newName)
{
*(this->mpName)=newName;//this here is what causes compiler error I think
//mpName=newName; Doesn't work because "no suitable conversion function from "const std::string" to "std::string *" exists"
}
The obvious answer is to not use a pointer in your class.
class NodeData
{
public:
void setname(const std::string &newName);
private:
std::string mpName;
};
void NodeData::setname(const std::string &newName)
{
mpName = newName;
}
Newbies often use pointers inappropriately, did you have a good reason for using a pointer in your class?
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.