473,657 Members | 2,283 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

ptr in collection item

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?

#include <vector>

class Item
{
public:
int iId;
void* pMiscMem; // will be allocd in ctor and deallocd in dtor
Item(int AiId) : iId(AiId) { pMiscMem = malloc(1024); }
~Item() { free(pMiscMem), pMiscMem = 0; }
};

class MyColl
{
public:
std::vector<Ite m> v;
MyColl() {}
void Add(Item* pItem) { v.push_back(*pI tem); }
};

void test_ptr_in_vec tor_item()
{
MyColl C;
for (int i = 0; i < 100; ++i)
C.Add(new Item(i));
}

Jul 23 '05 #1
13 1705
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".

V
Jul 23 '05 #2
Your copy constructor (automatically generated by the compiler) does not
allocate new memory. Are you trying to use heterogeneous containers like in
Java? You should avoid this.
Jul 23 '05 #3
"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); }

~Item()
{ free(pMiscMem), pMiscMem = 0; }

Item(const Item& Other)
{
free(pMiscMem);

iId = Other.iId;
pMiscMem = Other.pMiscMem;

Other.~Item();
}

const Item& operator=(const Item& Other)
{
free(pMiscMem);

iId = Other.iId;
pMiscMem = Other.pMiscMem;

Other.~Item();

return *this;
}
};

class MyColl
{
public:
std::vector<Ite m> v;
MyColl() {}
void Add(Item* pItem) { v.push_back(*pI tem); }
};

void test_ptr_in_vec tor_item()
{
MyColl C;
for (int i = 0; i < 100; ++i)
C.Add(new Item(i));
}
Jul 23 '05 #4
"Jason Heyes" wrote
Your copy constructor (automatically generated by the compiler) does not
allocate new memory. Are you trying to use heterogeneous containers like in Java?


I think not. Cf. code. The container shall contain objects of the same one type.


Jul 23 '05 #5
Remove 'free(pMiscMem) ' in your copy constructor and all lines containing
'Other.~Item()' .
Jul 23 '05 #6
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<Ite m> v;
MyColl() {}
void Add(Item* pItem) { v.push_back(*pI tem); }
};

void test_ptr_in_vec tor_item()
{
MyColl C;
for (int i = 0; i < 100; ++i)
C.Add(new Item(i));
}


Larry
Jul 23 '05 #7
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?

#include <vector>

class Item
{
public:
int iId;
void* pMiscMem; // will be allocd in ctor and deallocd in dtor
Item(int AiId) : iId(AiId) { pMiscMem = malloc(1024); }
~Item() { free(pMiscMem), pMiscMem = 0; }
};

class MyColl
{
public:
std::vector<Ite m> v;
MyColl() {}
void Add(Item* pItem) { v.push_back(*pI tem); }
};

void test_ptr_in_vec tor_item()
{
MyColl C;
for (int i = 0; i < 100; ++i)
C.Add(new Item(i));
}


There is a memory leak in the line:

C.Add(new Item(i));

You use 'new' to allocate an 'Item'.
A POINTER to that 'Item' is passed to Add() which
calls v.push_back(*pI tem). push_back() makes a
COPY of it's arg (a copy of "*pItem" in this case),
then puts that copy into the vector. The original
'Item' allocated by 'new' is never deleted.
Here's one possible alternative:

void test_ptr_in_vec tor_item()
{
MyColl C;
Item * pItem;

for (int i = 0; i < 100; ++i)
{
pItem = new Item(i);
C.Add(pItem);
delete pItem;
}
}

The name 'test_ptr_in_ve ctor()' is misleading.
You do not put a pointer to 'Item' (an "Item *")
in your vector; you put an actual 'Item'.

Larry
Jul 23 '05 #8
"Larry I Smith" wrote
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?


Nothing special. Just a sample for demo purposes.

~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.


Ok, got it.
But wouldn't it be faster if 'this' would just take the resources of 'Other'
and clear them in 'Other'? IOW transferring the ownership from
'Other' to 'this'. The following solution does it this way. Is it ok to do it so,
or is there anything against it?

class Item
{
public:
int iId;
void* pMiscMem; // will be allocd in ctor and deallocd in dtor

Item(int AiId) : iId(AiId)
{
pMiscMem = malloc(1024); // just a sample for ptr usage in collection items
}

~Item()
{
if (pMiscMem)
free(pMiscMem);
ClearOwnership( );
}

void ClearOwnership( )
{ // just clears the resources (but does not destroy them!)
// intended especially for ptrs.
// will be called from copy_ctor, assignment_oper ator, and dtor
pMiscMem = 0; // setting ptrs to 0 is important
iId = 0;
}

Item(const Item& Other)
{ // The object will be created (initialized) from the other one (Other),
// Therefore the normal ctor won't be called.
// So nothing is initialized yet!
// The initialization from Other is the job of this copy constructor.

// set resources of this from Other:
iId = Other.iId;
pMiscMem = Other.pMiscMem;

// take ownership by clearing Other:
((Item*) &Other)->ClearOwnership ();
}

const Item& operator=(const Item& Other)
{
// free resources of this:
free(pMiscMem);

// set resources of this from Other:
iId = Other.iId;
pMiscMem = Other.pMiscMem;

// take ownership by clearing Other:
((Item*) &Other)->ClearOwnership ();

return *this;
}
};

class MyColl
{
public:
std::vector<Ite m> v;
MyColl() {}
void Add(Item& rItem) { v.push_back(rIt em); }
};

void test_ptr_in_vec tor_item()
{
MyColl C;
for (int i = 1; i <= 10000; ++i)
{
Item obj(i);
C.Add(obj);
}
}
Jul 23 '05 #9
"Larry I Smith" 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?
.... void test_ptr_in_vec tor_item()
{
MyColl C;
for (int i = 0; i < 100; ++i)
C.Add(new Item(i));
}

There is a memory leak in the line:

C.Add(new Item(i));

You use 'new' to allocate an 'Item'.
A POINTER to that 'Item' is passed to Add() which
calls v.push_back(*pI tem). push_back() makes a
COPY of it's arg (a copy of "*pItem" in this case),
then puts that copy into the vector. The original
'Item' allocated by 'new' is never deleted.
Here's one possible alternative:

void test_ptr_in_vec tor_item()
{
MyColl C;
Item * pItem;

for (int i = 0; i < 100; ++i)
{
pItem = new Item(i);
C.Add(pItem);
delete pItem;
}
}


Thanks. Got it.
The name 'test_ptr_in_ve ctor()' is misleading.
You do not put a pointer to 'Item' (an "Item *")
in your vector; you put an actual 'Item'.


Yeah. It better should be "test_ptr_in_co llectionitem()"
Jul 23 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
2527
by: Marc L'Ecuyer | last post by:
Hi, I have a collection class derived from CollectionBase. This collection can add items of my class MyItem. In my class MyItem, I have a Selected property. When this property is set to true, I have to set this property to false for all other items in the collection (only 1 item can be selected). How can I do that? Thanks
5
2722
by: Kurt Bauer | last post by:
I have an ASP group calendar application which pulls calendar data from Exchange via webdav into an XML string. I then loop the XML nodes to populate a collection of appointments. Finally I use the appointment collection to populate the calendar control. The performance getting the XML data is fine, but loading the data into the collection is slow. My question/problem is should I be using the collection, a dataset, or something else to...
3
1640
by: ck | last post by:
Sorry for the cross post. What is wrong with this code?--ado recordset to populate a collection--see reason below Dim myCol2 As New Collection On Error Resume Next Do While Not rs.EOF myCol2.Add rs!Email, rs!Email rs.MoveNext Loop
7
2711
by: juli | last post by:
I have strings variables in a collection list and I want to create new collection but to add to it only strings that are distinct (no common strings). For example I have an object sentense which is the base for a collection and there are words in it and I want to create a new collection of sentenses where there is no similar secound word in those sentenses. How do I do this distinct selection from a collection of object? Thanks!
1
2157
by: Josema | last post by:
Hi, My problem is the next one (in a windows application): - I have a class derived from collectionbase to fill with persons object (id, name) from database. - I have a ListBox wich datasource its the collectionbase above. I want to do: - I would like that when i click in a item of the listbox, deletes from database the values of this item, and from collection too. Then refresh the listbox with the collection modified.
4
2513
by: Michael K. Walter | last post by:
I'd like to create a strongly-typed collection of objects that are indexed by a string value (key is a string). I'd also like to allow users to iterate over the collection using a For-each loop where an object of the contained type is returned (instead of just the standard DictionaryEntry object). - only allow objects of type MyObj to be added to the collection - return a MyObj type in the For-each loop What's the best way to do this?
3
2147
by: Matt Michael | last post by:
I have a listview control and a collection object right now that I'm trying to pass information to and from. Whenever I click on the checkbox, I want it to remove certain listview items and add them to the collection. Whenever I uncheck the checkbox, I want to add the items back into the listview from the collection, and remove them from the collection so I can do the process multiple times. The listview tag is being used as a key, so I...
2
3087
by: jmhmaine | last post by:
I've created a lookup class for a windows form application and I'm stuck on how on using the collection object. The process is simple, if the item is in the collection then return that object, if the item is not in the collection then create the item from a value in the database, then return it. Here is the code: Imports System.Data.SqlClient Public Class lookup
14
2375
by: Rich | last post by:
Yes, I need to store some values in an array type collection object that can hold 3 or more parameters per index. I have looked at the collection object, hashtable object and would prefer not to hassel with a multi-dimensional array. Is there such an object in VB.Net? Dim obj As someCollectionObj obj.Add("parmA1", "parmA2", "parmA3") obj.Add("parmB1", "parmB2", "parmB3") ....
6
7205
by: Arthur Dent | last post by:
How do you sort a generic collection derived from System.Collections.ObjectModel.Collection? Thanks in advance, - Arthur Dent
0
8411
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8323
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8739
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8513
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7351
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6176
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5638
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4173
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
1969
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.