hi i am delevop a multicontainner using templates, but i am getting a segmentation fault from the child class destructor, here is the code:
#include <algorithm>
#include <map>
#include <iostream>
class BaseType{
public:
virtual ~BaseType(){}
virtual BaseType * clone() const =0;
};
template<typename T>
class DataType : public BaseType
{
public:
DataType(const T & aValueData = T()):mValue(aValueData) {
// new DataType<T>(*this)
}
~DataType(){
}
BaseType * clone() const
{
return new DataType<T>(*this);
}
T mValue;
};
class MValueData
{
public:
template<typename T>
MValueData(T const & aAnyValue = T()):mTypeData(0),isDelete(false)
{
std::cout<<"Object Address before create object: "<<mTypeData<<std::endl;
mTypeData=new DataType<T>(aAnyValue);
std::cout<<"Object Address after create object"<<mTypeData<<std::endl;
}
~MValueData(){
std::cout<<"Object Address "<<mTypeData<<std::endl;
delete mTypeData;
mTypeData=0;
}
MValueData()
{
mTypeData=0;
}
template<typename T>
MValueData(const MValueData & aCopy)
{
mTypeData= new DataType<T>();
*mTypeData=aCopy.mTypeData;
}
template<typename T>
const MValueData & operator=(const MValueData & aCopy)
{
mTypeData= new DataType<T>();
*mTypeData=aCopy.mTypeData;
//MValueData(aCopia).swap(*this);
}
void swap(MValueData& other) {
std::swap(this->mTypeData, other.mTypeData);
}
template <typename T>
T& get()
{
return dynamic_cast<DataType<T>&>(*this->mTypeData).mValue;
}
bool operator <(const MValueData &rhs) const {
return (mTypeData<rhs.mTypeData);
}
template<typename T>
void setValue(T const & anyValue=T())
{
mTypeData= new DataType<T>(anyValue);
}
BaseType *mTypeData;
private:
bool isDelete;
};
int main()
{
MValueData aAnyType_1(0.22);
aAnyType_1.get<double>();
MValueData aAnyType_2(false);
std::map<MValueData , MValueData&> mMapa;
mMapa.insert(std::pair<MValueData , MValueData&>(aAnyType_1,aAnyType_2));
// mMapa.find(aAnyType_1);
return 0;
}
I am using GDB to determinate the bug but i cannot see proper way to fix, the segmentacion stop when i comment this line:
~MValueData(){
// if(mTypeData) delete mTypeData;
}
Only then it run propperly, but it seems that i am creating a memory leak.
Updated:std::map create copys of the object that i insert into, the object is destroyed twice, one when exit the main function and another when std::map is destroying it self,
any hint?
thx in advance!
This segmentation fault might appear to be in the destructor, but it is a problem in your copy constructor. Lets take a simple example, I have a class which stores a pointer. Then I copy this pointer value like you are doing: I will have two pointers to the same memory location. Now I delete one of these objects, thus deleting the value at the pointer. The second object will have a pointer to invalid memory, and when this tries to delete the memory you get a segmentation fault.
How to fix this:
Well there are a few ways actually. Firstly, you need to decide whether you want deep copying of the pointers or not. If you do, write a deep copy of the memory the pointer points too. If not I reocmmend using shared_ptr to avoid these sorts of problems.
Your copy constructor is broken. You are not cloning the object, but only the pointer. Once an object is copied, the two copies will try to delete the same real object in memory in the destructor and that will cause a crash. You need to figure out who should own the object and whether you want it cloned or shared among the different instances of the MValueData object. Then act accordingly to fix the issue.
Your copy constructor is not correct.
It only copies the pointer not the object.
The two objects copied with the copy constructor will try to delete the same object in their destructor.
Related
I'm trying to create a Read Only shared_ptr, shared between multiple instances. None of the instances should be able to modify the content of the pointer's object. But the instances should be able to copy it for an unknown period.
a const std::shared_ptr<T> cannot easily get stored in a attribute reference, as it has to be defined by the constructor. (and a const reference is, by definition, constant)
i did a wrapper class
template<class T>
class const_shared_ptr
{
public:
const_shared_ptr(std::shared_ptr<T> ptr)
{
m_ptr = ptr;
}
const T* get() const
{
return m_ptr.get();
}
private:
std::shared_ptr<T> m_ptr;
}
is this code clean ? or is there a more simpler way of doing ? this looks like a pretty easy problem but i can't figure any solution.
You can initialize a shared pointer to a const object from a shared pointer to a non-const object.
#include <memory>
void foo ()
{
auto v = std::make_shared <int> (10);
std::shared_ptr <int const> x = v;
// *x = 10; ERROR
}
I am having trouble with writing the Rule of three when it comes to vector of pointers to class objects. Searched and examples don't seem to apply. I have these three classes:
class Data
{
private:
map<string, double> m_DataVariables;
public:
Data();
Data(const Data &data);
};
class Sample
{
private:
Data *m_pData;
public:
virtual ~Sample()
{
delete m_pData;
}
Sample();
Sample(const Sample &sample);
};
class BuildTree
{
private:
vector<Sample*> BuildSamples;
public:
BuildTree(vector<Sample*> &Samples);
// This does not compile
BuildTree(const BuildTree& other) : BuildSamples(new(other.BuildSamples))
{
}
~TreeBuilding()
{
for (int i = 0; i < BuildSamples.size(); ++i)
delete BuildSamples[i];
}
void BuildTrees(void);
};
1- Not sure if I am correctly deleting BuildSamples.
2- In the constructor want to do a deep copy of the passed parameter into member variable BuildSamples.
BuildTree::BuildTree(vector<Sample*> &samples)
{
BuildSamples = samples; // This just copies the references
}
How do I write the copy constructor to make a deep copy? What am I missing here?
3- Please note: don't have access to smart pointers, share_ptr or unique_ptr, etc. C++98 is what I have.
Please show the steps required to do this. Really appreciate your time and consideration.
I noted you marked your question as c++98; even if C++98 doesn't support smart pointers in std::, you can certainly use the smart pointers defined in Boost, e.g. boost::shared_ptr.
For example, instead of using raw owning pointers like in vector<Sample*>, you can make your code simpler with
vector<boost::shared_ptr<Sample>>.
In this way, the copy and destruction operations will be automatically implemented under the hood.
You probably want something like:
BuildTree(const BuildTree& other)
{
BuildSamples.reserve(other.BuildSamples.size());
for (std::size_t i = 0; i != other.BuildSamples.size(); ++i) {
BuildSamples.push_back(new Sample(*other.BuildSamples[i]));
}
}
BuildTree(const vector<Sample*> &samples)
{
BuildSamples.reserve(samples.size());
for (std::size_t i = 0; i != samples.size(); ++i) {
BuildSamples.push_back(new Sample(*samples[i]));
}
}
You need to initialise the BuildSamples member as a vector of pointers, and ensure every pointer points at a clone of the objects passed. One way is
BuildTree(const BuildTree& other) : BuildSamples(other.BuildSamples)
{
std::vector<Sample *>::iterator i = BuildSamples.begin(), end = BuildSamples.end();
while (i != end)
{
*i = new Sample(**i);
++i;
}
}
The usage of BuildSamples(other.BuildSamples) initialises BuildSamples with the correct number of elements, but those elements are the same pointers as in other.BuildSamples. This ensures the vector is of the correct size, without worrying about setting the size explicitly. That is a shallow copy. The body of the constructor then sets every element of BuildSamples so it points at a clone of itself - thus completes the deep copy.
The constructor BuildTree(const std::vector<Sample *> &) can be implemented in a similar manner.
Note: given that your class is implementing a non-trivial copy constructor (to do the deep copy) and a destructor to cleanup, you also need to implement an assignment operator BuildTree &operator=(const BuildTree &). For an explanation why, look up the "rule of three".
While dealing with pointers and to avoid crashing of a running program due to destructor being called, Deep copy must be used! deep copy allows creating a new pointer pointing to a newly allocated space. But when passing objects as R-value in vector it is better to use the move constructor.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class example{
private:
int *pointer;
public:
//constructor
example(int d){
pointer = new int;
*pointer = d;
cout<<"Constructor Called"<<endl;
}
// deep copy
example(const example &source){
pointer = new int;
*pointer= *source.pointer;
cout<<"deep copy made"<<endl;
}
// Move Constructor
example(example &&source) noexcept :pointer{source.pointer}{
source.pointer = nullptr;
cout << "object moved"<<endl;
}
// Destructor
~example() {
delete pointer;
cout << "Destroyed"<<endl;
}
};
int main()
{
vector <example> vec;
vec.push_back(example{300});
vec.push_back(example{300});
vec.push_back(example{300});
vec.push_back(example{300});
return 0;
}
I wrote this template class for pointers usage
(I need smart pointers, but I can't use boost or C++11):
template<class T>
class TreePointer{
public:
TreePointer(){
isRefOnly=false;
data=NULL;
};
TreePointer(T* data){
this->data=data;
this->isRefOnly=false;
}
TreePointer(const TreePointer& anotherPtr){
this->data=anotherPtr.data;
this->isRefOnly=true;
}
virtual ~TreePointer(){
if (!isRefOnly){
delete data;
}
}
T* operator->() const{
return data;
}
void operator=(const TreePointer &anotherPtr){
this->data=anotherPtr.data;
this->isRefOnly=true;
}
private:
T* data;
bool isRefOnly;
};
And I have big class with many methods, like this:
class WrittenBigClassWithManyMethods{
public:
WrittenBigClassWithManyMethods(int v){
this->v=v;
}
int sum(WrittenBigClassWithManyMethods* a){
return v+a->v;
}
int v;
};
This usage of my smart pointers work perfectly:
TreePointer<WrittenBigClassWithManyMethods> tp(new WrittenBigClassWithManyMethods(5));
WrittenBigClassWithManyMethods* simpleClass=new WrittenBigClassWithManyMethods(5);
cout << tp->sum(simpleClass);
But it usage isn't work:
TreePointer<WrittenBigClassWithManyMethods> tp2(new WrittenBigClassWithManyMethods(5));
cout << tp->sum(tp2);
How i can change my template for pointers to make invoking methrod sum of class WrittenBigClassWithManyMethods with parameter of type TreePointer, without any changes for class WrittenBigClassWithManyMethods and its any usages? If this is not possible, how I minimize the changes for class WrittenBigClassWithManyMethods and its usage?
Usually you'll want to overload the unary operator * (de-reference) too, returning a T&. Then you can have both a reference and the original pointer by taking the address of the result:
tp1->method_that_takes_ref(*tp2); // With operator*()
tp1->method_that_takes_ptr(&*tp2); // Works, but syntax might be a bit surprising
Another way to get at the pointer inside would be to call operator -> directly, but that would be a bit awkward. You are likely better off providing some kind of "get" method, like the one in unique_ptr, that simply returns the raw pointer:
tp1->method_that_takes_ptr(tp2.operator->()); // Works, but ugh
tp1->method_that_takes_ptr(tp2.get()); // Much clearer
Add a conversion operator to T*:
operator T*() {
return data;
}
Now the compiler will call it whenever it wants to convert a TreePointer<SomeClass> to a SomeClass*.
Introduction
I have a data structure : pool of values. (not pool of pointers)
When I called create(), it will return Handle.
Everything is good so far.
template<class T> class Pool{
std::vector<T> v; //store by value
Handle<T> create(){ .... }
}
template<class T> class Handle{
Pool<T>* pool_; //pointer back to container
int pool_index_; //where I am in the container
T* operator->() {
return pool_->v.at(pool_index_); //i.e. "pool[index]"
}
void destroy(){
pool_-> ... destroy(this) .... mark "pool_index_" as unused, etc ....
}
}
Now I want Handle<> to support polymorphism.
Question
Many experts have kindly advised me to use weak_ptr, but I still have been left in blank for a week, don't know how to do it.
The major parts that I stuck are :-
Should create() return weak_ptr, not Handle?
.... or should Handle encapsulate weak_ptr?
If create() return weak_ptr for user's program, ...
how weak_ptr would know pool_index_? It doesn't have such field.
If the user cast weak_ptr/Handle to a parent class pointer as followed, there are many issues :-
e.g.
class B{}
class C : public B { ......
}
....
{
Pool<C> cs;
Handle<C> cPtr=cs.create();
Handle<B> bPtr=cPtr; // casting ;expected to be valid,
// ... but how? (weak_ptr may solve it)
bPtr->destroy() ; // aPtr will invoke Pool<B>::destroy which is wrong!
// Pool<C>::destroy is the correct one
bPtr.operator->() ; // face the same problem as above
}
Assumption
Pool is always deleted after Handle (for simplicity).
no multi-threading
Here are similar questions, but none are close enough.
C++ object-pool that provides items as smart-pointers that are returned to pool upon deletion
C++11 memory pool design pattern?
Regarding weak_ptr
A std::weak_ptr is always associated with a std::shared_ptr. To use weak_ptr you would have to manage your objects with shared_ptr. This would mean ownership of your objects can be shared: Anybody can construct a shared_ptr from a weak_ptr and store it somewhere. The pointed-to object will only get deleted when all shared_ptr's are destroyed. The Pool will lose direct control over object deallocation and thus cannot support a public destroy() function.
With shared ownership things can get really messy.
This is one reason why std::unique_ptr often is a better alternative for object lifetime management (sadly it doesn't work with weak_ptr). Your Handle::destroy() function also implies that this is not what you want and that the Pool alone should handle the lifetime of its objects.
However, shared_ptr/weak_ptr are designed for multi-threaded applications. In a single-threaded environment you can get weak_ptr-like functionality (check for valid targets and avoid dangling pointers) without using weak_ptr at all:
template<class T> class Pool {
bool isAlive(int index) const { ... }
}
template<class T> class Handle {
explicit operator bool() const { return pool_->isAlive(pool_index_); }
}
Why does this only work in a single-threaded environment?
Consider this scenario in a multi-threaded program:
void doSomething(std::weak_ptr<Obj> weak) {
std::shared_ptr<Obj> shared = weak.lock();
if(shared) {
// Another thread might destroy the object right here
// if we didn't have our own shared_ptr<Obj>
shared->doIt(); // And this would crash
}
}
In the above case, we have to make sure that the pointed-to object is still accessible after the if(). We therefore construct a shared_ptr that will keep it alive - no matter what.
In a single-threaded program you don't have to worry about that:
void doSomething(Handle<Obj> handle) {
if(handle) {
// No other threads can interfere
handle->doIt();
}
}
You still have to be careful when dereferencing the handle multiple times. Example:
void doDamage(Handle<GameUnit> source, Handle<GameUnit> target) {
if(source && target) {
source->invokeAction(target);
// What if 'target' reflects some damage back and kills 'source'?
source->payMana(); // Segfault
}
}
But with another if(source) you can now easily check if the handle is still valid!
Casting Handles
So, the template argument T as in Handle<T> doesn't necessarily match the type of the pool. Maybe you could resolve this with template magic. I can only come up with a solution that uses dynamic dispatch (virtual method calls):
struct PoolBase {
virtual void destroy(int index) = 0;
virtual void* get(int index) = 0;
virtual bool isAlive(int index) const = 0;
};
template<class T> struct Pool : public PoolBase {
Handle<T> create() { return Handle<T>(this, nextIndex); }
void destroy(int index) override { ... }
void* get(int index) override { ... }
bool isAlive(int index) const override { ... }
};
template<class T> struct Handle {
PoolBase* pool_;
int pool_index_;
Handle(PoolBase* pool, int index) : pool_(pool), pool_index_(index) {}
// Conversion Constructor
template<class D> Handle(const Handle<D>& orig) {
T* Cannot_cast_Handle = (D*)nullptr;
(void)Cannot_cast_Handle;
pool_ = orig.pool_;
pool_index_ = orig.pool_index_;
}
explicit operator bool() const { return pool_->isAlive(pool_index_); }
T* operator->() { return static_cast<T*>( pool_->get(pool_index_) ); }
void destroy() { pool_->destroy(pool_index_); }
};
Usage:
Pool<Impl> pool;
Handle<Impl> impl = pool.create();
// Conversions
Handle<Base> base = impl; // Works
Handle<Impl> impl2 = base; // Compile error - which is expected
The lines that check for valid conversions are likely to be optimized out. The check will still happen at compile-time! Trying an invalid conversion will give you an error like this:
error: invalid conversion from 'Base*' to 'Impl*' [-fpermissive]
T* Cannot_cast_Handle = (D*)nullptr;
I uploaded a simple, compilable test case here: http://ideone.com/xeEdj5
I am trying to make a basic any style class in C++, called object. It compiles successfully, but before anything happens, I get the error: Unhandled exception at 0x008128C1 in object.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC.:
#include <typeinfo>
struct object
{
public:
template < typename T > struct Data
{
public:
Data(T value) : val_(&value){}
Data() : val_(nullptr){}
T* value()
{
return val_;
}
~Data()
{
delete &val_;
}
template < typename Tn > void Swap(Data<Tn>* D)
{
if (std::is_destructible<T>())
{
val_->~T();
}
Tn n_val = (Tn)val_;
std::swap<Tn>(&n_val, D->value());
}
private:
T* val_;
};
struct Inner : Data<void*>
{
template < typename T > void Cast()
{
Swap<T>(new Data<T>((T)NULL));
}
template < typename T > void Cast(const T& value)
{
Swap<T>(new Data<T>(value));
}
};
private:
Inner* Held;
public:
template < typename T > object(const T& value)
{
Held->Cast<T>(value);
}
template < typename T > void operator=(const T& value)
{
Held->Cast<T>(value);
}
template < typename T > void cast()
{
Held->Cast<T>();
}
template < typename T > void cast(const T& value)
{
Held->Cast<T>(value);
}
~object(){ delete Held; }
const void* operator()() const
{
return *Held->value();
}
};
And then in my test file
#include <iostream>
int main()
{
object MyObject = 5;
std::cout << MyObject();
}
Notice that you are doing delete Held; even though you never usednew. You never actually assign anything to Held, so it is uninitialized when you attempt to do Held->Cast<T>(value);. You're going to have to allocate a Held object in some way before you can do that.
You also have a problem your Data struct. Its constructor takes a copy of its argument, and then you store a pointer to that copy. That copy is local to the constructor though and will be destroyed when the constructor ends. The val_ pointer is left pointing at the destroyed object. Not only that, but you then do delete &val_; which attempts to deallocate the object that had automatic storage duration.
You really shouldn't be using new and delete as much as you are, and you would avoid many of the problems you're having.
Your object class is expecting data that has been allocated on the heap. This can be seen since you are accessing that data via a pointer in your object class, swapping its value, and deleting that pointer.
In your main function you are building an object with a literal value of 5. This value has not been allocated on the heap because no allocation was called for (no call to new exists). 5 may have been allocated on the stack, but as a literal it might also be stored in program ROM by the compiler, or any other location where it is dangerous to access the memory address.
The moment your code attempts to modify the data at the address of the literal value 5, you have committed an access violation because you are accessing memory that you are not allowed by your program to modify directly.
To solve this you probably want your object class to allocate a copy of the data being passed to it on the heap that it can then take ownership of and modify and delete at will.