tuvok wrote:
> "Victor Bazarov" wrote
>>tuvok wrote:
>>>I have an Item object which allocates memory in its ctor
>>>and frees it in its dtor.
>>>I want to add such items to a vector. But the program crashes. Why?
>>>How do I fix it?
>>>
>>Read about "the Rule of Three".
>
> Thank you. I did and came up with the following but it still crashes 
> What's missing?
>
> class Item
> {
> public:
> int iId;
> void* pMiscMem; // will be allocd in ctor and deallocd in dtor
>
> Item(int AiId) : iId(AiId), pMiscMem(0)
> { pMiscMem = malloc(1024); }
Try using 'new' and delete[], rather than malloc() and free()?
Why is pMiscMem "void *", what will it hold?
>
> ~Item()
> { free(pMiscMem), pMiscMem = 0; }
>
> Item(const Item& Other)
> {
> free(pMiscMem);
>
> iId = Other.iId;
> pMiscMem = Other.pMiscMem;
This is a copy constructor, you should be making
a copy of "Other" - not taking over its data.
You should replace the above line with something
like this:
pMiscMem = malloc(1024);
memcpy(pMiscMem, Other.pMiscMem, 1024);
Otherwise you'll have 2 Item objects who's pMiscMem
pointers point to the same memory block. When either
of those Item objects is destructed, the memory that
both Item.pMiscMem members point to will be deleted.
That will leave the pMiscMem of the remaining 'Item'
object pointing to memory that already been freed;
causing a crash when the 2nd Item object is destructed.
>
> Other.~Item();
Don't delete 'Other' in your copy constructor.
The purpose of the copy constructor is to make a copy
of 'Other' - and that's all.
> }
>
> const Item& operator=(const Item& Other)
> {
> free(pMiscMem);
>
> iId = Other.iId;
> pMiscMem = Other.pMiscMem;
This is an assignmet operator, you should be making
a copy of "Other" - not taking over its data.
You should replace the above line with something
like this:
pMiscMem = malloc(1024);
memcpy(pMiscMem, Other.pMiscMem, 1024);
Otherwise you'll have 2 Item objects who's pMiscMem
pointers point to the same memory block. When either
of those Item objects is destructed, the memory that
both Item.pMiscMem members point to will be deleted.
That will leave the pMiscMem of the remaining 'Item'
object pointing to memory that already been freed;
causing a crash when the 2nd Item object is destructed.
>
> Other.~Item();
Don't delete 'Other' in your assignment operator.
The purpose of the assignment operator is to make a
copy of the data from 'Other' in 'this' - and that's all.
>
> return *this;
> }
> };
>
> class MyColl
> {
> public:
> std::vector<Item> v;
> MyColl() {}
> void Add(Item* pItem) { v.push_back(*pItem); }
> };
>
> void test_ptr_in_vector_item()
> {
> MyColl C;
> for (int i = 0; i < 100; ++i)
> C.Add(new Item(i));
> }
>
>
Larry