Segmentation fault on list.begin() - c++

I have this member function in my Folder class:
string _recFullPath() {
list<Folder*> folders;
list<Folder*>::iterator it = folders.begin();
folders.push_front(this);
it = folders.begin();
while((*it)->hasParent()) {
folders.push_front((*it)->parent());
it = folders.begin();
}
folders.push_back(this);
for(it = folders.begin(); it != folders.end(); ++it) {
cout << (*it)->getName() << "/";
}
}
This does compile, but when it comes to it = folders.begin(), in the while loop it gives a segmentation fault, and I cannot figure out why.
The layout for a Folder object is this:
class Folder {
private:
Folder* _parent;
string _name;
string _fullPath;
string _recStrFullPath;
bool _hasParent;
public:
Folder(string name) {
this->_name = name;
this->_hasParent = false;
}
Folder(string name, Folder* parent) {
this->_parent = parent;
this->_name = name;
this->_hasParent = true;
}
Folder* parent() {
return this->_parent;
}
string getName() {
return this->_name;
}
};
And of course the above mentioned function. Can someone see what I'm doing wrong in the above code?

I don’t know why your while loop uses the iterator at all. This would be cleaner and simpler:
list<Folder*> folders;
Folder* current = this;
while (current->hasParent()) {
folders.push_front(current);
current = current.parent();
}
folders.push_front(current);
for(list<Folder*>::const_iterator i = folders.begin(); i != folders.end(); ++i) {
cout << (*i)->getName() << "/";
}

It's not normally good form to require the use of pointers in a class without managing the storage in that class. At very least, you would have to make it very clear just how allocation requirements of the caller are supposed to work. Here's some code to illustrate:
Folder foo(){
Folder bar("bar");
Folder baz("baz", &bar);
return baz;
}
What happens here is pretty ugly, but it looks like you did what you were supposed to. What happens at the return is that baz gets copied into the storage location it needs to go to for the caller, but baz is retaining a pointer to bar. bar (and the original baz, you have a copy now) are gone, freed from the stack at the end of the function.
There are a few ways to get out of this mess. The right way is probably to manage memory completely in the class itself. here's an alternative version:
class Folder {
private:
Folder* _parent;
string _name;
string _fullPath;
string _recStrFullPath;
bool _hasParent;
public:
Folder(const Folder & src)
: _name(src._name), _fullPath(src._fullPath)
, _recStrFullPath(src._recStrFullPath)
{
if (src._parent) {
_parent = new Folder(src._parent);
}
}
~Folder() {
delete _parent;
}
Folder(string name) {
this->_name = name;
this->_hasParent = false;
}
Folder(string name, const Folder & parent) {
this->_parent = new Folder(parent);
this->_name = name;
this->_hasParent = true;
}
Folder* parent() {
return this->_parent;
}
string getName() {
return this->_name;
}
};
The important changes are that instead of taking a pointer when making a child node, you actually duplicate the parent node into the child. the child has its' very own copy. It also looks after that copy so the caller doesn't have to care about it at all.
To make this work, some changes to the class were necessary. The call signature of the child forming constructor was changed to make it clear that the parent is not affected. When filling in the _parent, a copy gets made with new.
To facilitate this, it was necessary to add another constructor, a copy constructor, since we need to care for the _parent node specially.
Finally, since we are doing these allocs in the class itself, its necessary to add a destructor to clean up those allocs when the instance goes away.
Now, the caller can look like this:
Folder foo(){
Folder bar("bar");
Folder baz("baz", bar);
return baz;
}
and work politely.

Related

Copy And Assignment: How to Deep Copy? C++

I have two classes that are essentially string classes that look like this.
The first class holds a string as a member and the second class also holds a string plus an array of pointers for the 'MenuItem' class and also a tracker.
const int MAX_NO_OF_ITEMS = 10;
class Menu; // forward declaration
class MenuItem {
char* Menuitem;
//member functions
MenuItem();
...
~MenuItem();
friend Menu;
};
class Menu {
private:
char* m_Title;
MenuItem* m_MenuItems[MAX_NO_OF_ITEMS];
int m_menuTracker;
... //other functions not shown
}
I want to be able to deep copy one Menu object to another Menu object but the way I am doing it seems do be as if it were a shallow copy when it comes to copying over the 'm_MenuItems'. I know for sure that the 'm_Title' member is getting deep copied as I am creating a 'new' char* for it but the problem arises when I am trying to copy the source 'm_MenuItems' to the destination as they end up sharing the same memory. This causes problems because when the deconstructor is called, it is called twice on the same object, causing my program to crash.
Here is my copy and assignment code:
Menu& Menu::operator=(const Menu& src) {
if (this != &src && src.m_Title != nullptr) {
delete[] m_Title;
m_Title = nullptr;
m_Title = new char[strlen(src.m_Title) + 1];
strcpy(m_Title, src.m_Title);
//if current object has menuItems, then delete to make room for src.
for (int i = 0; i < m_menuTracker; i++) {
delete m_MenuItems[i];
this->m_MenuItems[i] = nullptr;
}
This following for-loop is where my problem arises...
if (src.m_MenuItems[0] != nullptr) {
for (int i = 0; i < src.m_menuTracker; i++) {
m_MenuItems[i] = src.m_MenuItems[i];
}
this->m_menuTracker = src.m_menuTracker;
}
else
this->m_menuTracker = 0;
}
else {
this->setEmpty();
}
return *this;
}
How am I supposed to allocate a new block of memory for the destination 'm_MenuItems'?

Why std::iterator is not able to access the function

When I try to access a function through iterator the compile tells that class ha no member with such name.
class Director
{
private:
std::string stdstrName;
public:
Director(std::string name): stdstrName(name){ }
void setName(std::string name) { stdstrName = name; }
std::string getName() { return stdstrName; }
};
int main(){
std::vector<std::shared_ptr<Director>> stdVecDir;
std::shared_ptr<Director> pointer1 = std::make_shared<Director>("Director1");
std::shared_ptr<Director> pointer2 = std::make_shared<Director>("Director2");
std::shared_ptr<Director> pointer3 = std::make_shared<Director>("Director3");
stdVecDir.push_back(pointer1);
stdVecDir.push_back(pointer2);
stdVecDir.push_back(pointer3);
auto it = std::find(stdVecDir.begin(), stdVecDir.end(), [](std::shared_ptr<Director> dir) { return dir->getName() == "Director2"; });
if (it != std::end(stdVecDir))
std::cout << *it->getName(); // compiler complains that getName() is not a member of class Director
}
Why does the compile complains that getName() is not a member of class Director.
You are using std::find(), but it's used with values, not with callables, hence you need to use std::find_if.
And you are using your iterator to access to a member function of an object pointed to by a pointer which is pointed to by an iterator, hence you have two dereferences, not one.
The following is a correction
auto it = std::find_if(stdVecDir.begin(), stdVecDir.end(),
[](std::shared_ptr <Director> dir) { return dir->getName() == "Director2"; });
if (it != std::end(stdVecDir))
std::cout << it->get()->getName(); //or (*it)->getName();
If im not mistaken you need to change it to (*it)-> to access Director from iterator and shared_ptr. With *it-> you are accessing shared_ptr from the iterator.

Why is my code getting a segmentation error

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.

Class member to point to a specific node member of an STL list?

How can I store a pointer to the name of a person's spouse as a private member of the person's class?
For example, say I have the following code:
#include <iostream>
#include <list>
using namespace std;
class person
{
private:
string name;
string *spouse;
public:
void setName(string tempName) { name = tempName; }
void setSpouse(string &tempSpouse) { spouse = &tempSpouse; } // ERROR HERE?
string getName() { return name; }
string getSpouse() { return spouse; } // ERROR HERE?
};
int main()
{
person entry;
list<person> personList;
list<person>::iterator itr1, itr2;
/* Adding two people/nodes to the linked list. */
entry.setName("John Doe");
personList.push_back(entry);
entry.setName("Tina Doe");
personList.push_back(entry);
/* Attempting to assign Tina Doe as John Doe's spouse. */
for (itr1 = personList.begin(); itr1 != personList.end(); itr1++)
{
if (itr1->getName() == "John Doe")
{
for (itr2 = personList.begin(); itr2 != personList.end(); itr2++)
{
if (itr2->getName() == "Tina Doe")
{
itr1->setSpouse(itr2->getName()); // ERROR HERE?
}
}
}
}
/* Displaying all Names with Spouses afterwards. */
for (itr1 = personList.begin(); itr1 != personList.end(); itr1++)
{
cout << "Name: " << itr1->getName() << " | Spouse: " << itr1->getSpouse() << endl;
}
return 0;
}
I am unable to assign the address of the spouses name to the pointer member in the class. I've noted in the comments where I believe the errors might be.
You can view the code and errors here: https://ideone.com/4CXFnt
Any help will be greatly appreciated. Thank you.
getName returns a temporary std::string (copy of the name variable), and the compiler is trying to save you from referencing a part of memory that will be soon deleted. This error has nothing to do with lists - to fix it you need to either store copies in spouse variable (which will result in storing same data in multiple places) or return a reference in getName. You can also consider creating another accessor (private one), but it's ugly.
I'd recommend storing copies, but if references/pointes are really required then it's sufficient to modify lines:
string getName() { return name; }
string getSpouse() { return spouse; } // ERROR HERE?
to
string& getName() { return name; }
string getSpouse() { return *spouse; } // ERROR HERE?
however, for consistency I'd recommend:
string& getName() { return name; }
string& getSpouse() { return *spouse; } // ERROR HERE?
You have two problems. The first is easy to fix: getSpouse doesn't return the right type. You should write
string getSpouse() { return *spouse; } // Derefencing the pointer and returning a string
// or
string* getSpouse() { return spouse; } // Returning the pointer
The second problem is more subtle. When you write: itr2->getName() , you only have a value (a copy of itr2->name): you do not store a variable that you will be able to change, so you cannot make a reference to it.
There is no easy way you can have a pointer in a class instance pointing the a private variable of another instance. I guess you should question the way you are doing things and create a pointer to the person and not to the name (remember pointer are cheap, they are just memory locations).
class person
{
private:
string name;
person *spouse;
public:
void setSpouse(person *_spouse) { spouse = _spouse; }
person* getSpouse() { return spouse; }
string getSpouseName() { return spouse->getName(); }
};
This work, but still it is not safe: if spouse is destroyed and try to access it from person, you will run into deep problems… (note that you had the same problem with the string).
So what is the fix? Well, if you only want B to be the spouse of A, you can create B first and make a reference in A with a constructor. But if you want B to be the spouse of A and A the spouse of B, you have to use either the unsafe trick above and be careful, or stock the spouses' list outside the class.

Print out the values stored in vars of different classes, that have the same ancestor

I have this class:
class CComputer {
public:
// constructor
CComputer(string name) {
this->name = name;
};
// overloaded operator << for printing
friend ostream& operator<<(ostream& os, const CComputer& c);
// adds some component for this computer
CComputer & AddComponent(Component const & component) {
this->listOfComponents.push_back(component);
return *this;
};
// sets address for this computer
CComputer & AddAddress(const string & address) {
this->address = address;
return *this;
};
string name;
string address;
list<Component> listOfComponents;
};
and then these classes:
// ancestor for other classes...It's really dummy yet, but I dunno what to add there
class Component {
public:
Component() {};
~Component() {};
};
class CCPU : public Component {
public:
CCPU(int cores, int freq) {
this->cores = cores;
this->freq = freq;
};
int cores;
int freq;
};
class CMemory : public Component {
public:
CMemory(int mem) {
this->mem = mem;
};
int mem;
};
Now I feed my CComputer class with some values:
CComputer c("test.com");
c . AddAddress("123.45.678.910") .
AddComponent(CCPU(8, 2400)) .
AddComponent(CCPU(8, 1200)).
AddComponent(CMemory(2000)).
AddComponent(CMemory(2000)));
And now I would like to print it out with all the info I've put in there (CCPU & CMemory details including)
but how to implement it, to be able to iterate through CComputer::listOfComponents and don't care if I acctually access CCPU or CMemory ? I can add it to that list, but I have really no idea, how to make it, to be able to access the variables of those components.
So the output should look like:
##### STARTING #####
CComputer:
name:test.com
address:123.45.678.910
CCPU:
cores:8,freq:2400
CCPU:
cores:8, freq:1200
CMemory:
mem:2000
CMemory:
mem:2000
###### FINISHED! #####
As others have mentioned, you need to implement a virtual function (e.g. virtual std::string ToString() const = 0;) in the base class that is inherited and overridden by each child class.
However, that isn’t enough. Your code exhibits slicing which happens when you copy your child class instances into the list: the list contains objects of type Component, not of the relevant child class.
What you need to do is store polymorphic instances. Values themselves are never polymorphic, you need to use (smart) pointers or references for this. References are out, however, since you cannot store them in a standard container (such as std::list). Using raw pointers is considered bad style nowadays, but judging from the naming conventions of your classes you don’t learn modern C++ in your class (sorry!).
Therefore, raw pointers is probably the way to go. Change your code accordingly:
Store a list of pointers:
list<Component*> listOfComponents;
Make the argument type of AddComponent a pointer instead of const&.
Call the function by passing a newed object, e.g.:
AddComponent(new CCPU(8, 2400))
Now your code leaks memory left, right and center. You need to implement a destructor to free the memory:
~CComputer() {
typedef std::list<Component*>::iterator iter_t;
for (iter_t i = listOfComponents.begin(); i != listOfComponents.end(); ++i)
delete *i;
}
But now your code violates the Rule of Three (read this article! It’s important, and it may be the most useful thing about C++ you’re going to learn in this programming class) and consequently you also need to implement the copy constructor and copy assignment operator. However, we can’t. Sorry. In order to implement copying for your class, you would have to implement another virtual function in your Component class, namely one that clones an object (virtual Component* Clone() const = 0;). Only then can we proceed.
Here’s a sample implementation in CCPU:
Component* Clone() const {
return new CCPU(cores, freq);
}
… this needs to be done in all classes deriving from Component, otherwise we cannot correctly copy an object of a type that derives from Component and is hidden behind a pointer.
And now we can implement copying in the CComputer class:
CComputer(CComputer const& other)
: name(name)
, address(addess) {
typedef std::list<Component*>::iterator iter_t;
for (iter_t i = other.listOfComponents.begin(); i != other.listOfComponents.end(); ++i)
listOfComponents.push_back((*i)->Clone());
}
CComputer& operator =(CComputer const& other) {
if (this == &other)
return *this;
name = other.name;
address = other.address;
listOfComponents.clear();
for (iter_t i = other.listOfComponents.begin(); i != other.listOfComponents.end(); ++i)
listOfComponents.push_back((*i)->Clone());
return *this;
}
This code is brittle, not thread-safe and error-prone and no competent C++ programmer would ever write this1. Real code would for instance use smart pointers instead – but as mentioned before I’m pretty sure that this would be beyond the scope of the class.
1 What does this make me now, I wonder?
Just add a virtual method to Class Component called e.g. toString(), which returns a string describing the component. Then you can iterate through all components and call toString() without worrying about exactly what each component is. If you do that, then for each computer you would be able to print out the values of all the components.
However, as pointed out in one of the comments, the example output you give in the question outputs the CCPU for all computers, then all the memory for all computers. To order the output like that, you'll need to add another virtual method to Component called e.g. getType() which returns an enum or integer that represents the type of the information. You can then have two for-next loops, one nested inside the other, where the outer loop iterates through all the types and the inner loop iterating through all the computers calling the toString() on all components which match the type specified in the outer for loop.
Here's something that implements this idea.
#include <iostream>
#include <string>
#include <list>
using namespace std;
int const TYPE_CCPU = 1;
int const TYPE_MEMORY = 2;
class Component {
public:
virtual int GetType() { return -1; }
virtual std::string ToString() const {
return "OOPS! Default `ToString` called";
}
};
class CComputer {
public:
typedef std::list<Component*>::iterator iter_t;
// constructor
CComputer(string name) {
this->name = name;
};
~CComputer() {
for (iter_t i = listOfComponents.begin(); i != listOfComponents.end(); ++i) {
delete *i;
}
}
// overloaded operator << for printing
friend ostream& operator<<(ostream& os, const CComputer& c);
// adds some component for this computer
CComputer & AddComponent(Component *component) {
this->listOfComponents.push_back(component);
return *this;
};
// sets address for this computer
CComputer & AddAddress(const string & address) {
this->address = address;
return *this;
};
void PrintType(int type) {
for (iter_t i = listOfComponents.begin(); i != listOfComponents.end(); ++i) {
if ((*i)->GetType() == type)
std::cout << (*i)->ToString() << '\n';
}
}
string name;
string address;
list<Component*> listOfComponents;
};
class CCPU : public Component {
public:
CCPU(int cores, int freq) {
this->cores = cores;
this->freq = freq;
};
int GetType() { return TYPE_CCPU; }
std::string ToString() const {
return "CCPU::ToString()";
}
int cores;
int freq;
};
class CMemory : public Component {
public:
CMemory(int mem) { this->mem = mem; };
int GetType() { return TYPE_MEMORY; }
std::string ToString() const {
return "CMemory::ToString()";
}
int mem;
};
typedef std::list<CComputer*>::iterator iter_c;
int main() {
list<CComputer*> computerlist;
CComputer *c1 = new CComputer("test.com"), *c2 = new CComputer("test2.com");
c1->AddAddress("123.45.678.910").
AddComponent(new CCPU(8, 1200)).
AddComponent(new CMemory(2000));
computerlist.push_back(c1);
c2->AddAddress("987.65.432.10").
AddComponent(new CCPU(8, 2400)).
AddComponent(new CMemory(4000));
computerlist.push_back(c2);
for(int t=TYPE_CCPU; t<=TYPE_MEMORY; t++)
for (iter_c i = computerlist.begin(); i != computerlist.end(); ++i) {
(*i)->PrintType(t);
}
for (iter_c i = computerlist.begin(); i != computerlist.end(); ++i) {
delete (*i);
}
}
Implement ToString() in each of your classes. In .NET this is a standard even the "object" type implements.