473,382 Members | 1,078 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

STL removal algorithm question


Howdy

I have code similar to this in my project:

Note: BSTR is an abomination conjured up some disturbed person in the
COM world. BSTR strings must be allocated/deallocated using the
SysAllocString/SysFreeString Windows APIs.

typedef struct tagMyStruct
{
BSTR somestring;
BSTR someotherstring;
} MyStruct;

vector<MyStruct> my_struct;

over the course of my app, I allocate the BSTRs inside MyStruct and
stuff them into the vector.

When the time comes to get rid of them I was wondering if there is a
way to free the memory pointed to by the BSTR's in every MyStruct
instance inside the vector using a _single_ STL algorithm call?
Currently I use a combination of for_each (with a predicate to delete
the BSTRs) followed by a call to my_struct.erase(mystruct.begin(),
mystruct.end()).

There must be a better way to do this, right?

I looked up remove and remove_if, but they don't seem to be right for
my situation...

Apr 26 '06 #1
11 2341
Dilip wrote:
I have code similar to this in my project:

Note: BSTR is an abomination conjured up some disturbed person in the
COM world. BSTR strings must be allocated/deallocated using the
SysAllocString/SysFreeString Windows APIs.
Noted.
typedef struct tagMyStruct
{
BSTR somestring;
BSTR someotherstring;
} MyStruct;
Please use C++ way of defining types, it's so much easier:

struct MyStruct
{
BSTR somestring;
BSTR someotherstring;
};

vector<MyStruct> my_struct;

over the course of my app, I allocate the BSTRs inside MyStruct and
stuff them into the vector.
Do you allocate those BSTR yourself? Why not give it to MyStruct to
allocate? You know, like, in a constructor, for example...
When the time comes to get rid of them I was wondering if there is a
way to free the memory pointed to by the BSTR's in every MyStruct
instance inside the vector using a _single_ STL algorithm call?
Define the destructor in MyStruct. Make it deallocate those things.
Of course, to follow the Rule of Three, you will need to define the
copy c-tor and the assignment op as well.

After that, a simple destruction of the vector will free up all the
things.
Currently I use a combination of for_each (with a predicate to delete
the BSTRs) followed by a call to my_struct.erase(mystruct.begin(),
mystruct.end()).
OK
There must be a better way to do this, right?
There must be. Dynamic memory management needs to be the responsibility
of the owner of that memory. So, let MyStruct handle its own memory as
it should.
I looked up remove and remove_if, but they don't seem to be right for
my situation...


They are not.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 26 '06 #2

"Dilip" <rd*****@lycos.com> wrote in message
news:11**********************@t31g2000cwb.googlegr oups.com...

Howdy

I have code similar to this in my project:

Note: BSTR is an abomination conjured up some disturbed person in the
COM world. BSTR strings must be allocated/deallocated using the
SysAllocString/SysFreeString Windows APIs.

typedef struct tagMyStruct
{
BSTR somestring;
BSTR someotherstring;
} MyStruct;

vector<MyStruct> my_struct;

over the course of my app, I allocate the BSTRs inside MyStruct and
stuff them into the vector.

When the time comes to get rid of them I was wondering if there is a
way to free the memory pointed to by the BSTR's in every MyStruct
instance inside the vector using a _single_ STL algorithm call?
Currently I use a combination of for_each (with a predicate to delete
the BSTRs) followed by a call to my_struct.erase(mystruct.begin(),
mystruct.end()).

There must be a better way to do this, right?

I looked up remove and remove_if, but they don't seem to be right for
my situation...


struct MyStruct
{
BSTR somestring;
BSTR someotherstring;
MyStruct(/* params */)
{
// allocate
}

~MyStruct()
{
// de-allocate
}
};

-Mike
Apr 26 '06 #3
Victor Bazarov wrote:
Dilip wrote:
Please use C++ way of defining types, it's so much easier:

struct MyStruct
{
BSTR somestring;
BSTR someotherstring;
};


I would except for that damocle's sword called "company policy"

vector<MyStruct> my_struct;

over the course of my app, I allocate the BSTRs inside MyStruct and
stuff them into the vector.


Do you allocate those BSTR yourself? Why not give it to MyStruct to
allocate? You know, like, in a constructor, for example...


See, the problem is I simplified this struct a little too much. This
struct gets used across COM boundaries so I have to put it in a IDL
file and once I do that I don't think I can start adding ctors/dtors
and other stuff.
When the time comes to get rid of them I was wondering if there is a
way to free the memory pointed to by the BSTR's in every MyStruct
instance inside the vector using a _single_ STL algorithm call?


Define the destructor in MyStruct. Make it deallocate those things.
Of course, to follow the Rule of Three, you will need to define the
copy c-tor and the assignment op as well.


Apologies for the silly question but I presume vector.erase will call
dtor of the contained objects? If not I may not be able to use this
because the vector undergoes erasure/insertion during the lifetime of
my application and during such erasure I want to be able to free up the
BSTRs memory allocated inside every instance of MyStruct. IOW I have
engineered a situation where the capacity of the vector remains intact
-- its just its size() that contracts & expands.
I looked up remove and remove_if, but they don't seem to be right for
my situation...


They are not.


Thanks for confirming. I read Items 33/34 of Scott Meyers ESTL just
now -- I won't even go near it!

Apr 26 '06 #4
* Victor Bazarov:
Dilip wrote:
I have code similar to this in my project:

Note: BSTR is an abomination conjured up some disturbed person in the
COM world. BSTR strings must be allocated/deallocated using the
SysAllocString/SysFreeString Windows APIs.


Noted.
typedef struct tagMyStruct
{
BSTR somestring;
BSTR someotherstring;
} MyStruct;


Please use C++ way of defining types, it's so much easier:

struct MyStruct
{
BSTR somestring;
BSTR someotherstring;
};
vector<MyStruct> my_struct;

over the course of my app, I allocate the BSTRs inside MyStruct and
stuff them into the vector.


Do you allocate those BSTR yourself? Why not give it to MyStruct to
allocate? You know, like, in a constructor, for example...
When the time comes to get rid of them I was wondering if there is a
way to free the memory pointed to by the BSTR's in every MyStruct
instance inside the vector using a _single_ STL algorithm call?


Define the destructor in MyStruct. Make it deallocate those things.
Of course, to follow the Rule of Three, you will need to define the
copy c-tor and the assignment op as well.


That will be hugely inefficient when a MyStruct is copied within the
vector, as happens e.g. when the vector reallocates.

One slightly less inefficient way could be to use boost::shared_ptr to
encapsulate a BSTR (the BSTR type is a pointer).

But, personally I'd encapsulate that vector in a class, because it's
evidently an implementation of something with a very restricted set of
operations, and use an ordinary for loop in the class' destructor.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Apr 26 '06 #5
Dilip wrote:
[..]
Apologies for the silly question but I presume vector.erase will call
dtor of the contained objects?
That is correct. How does it help you? Your MyStruct has no d-tor,
and the one that the compiler creates for you won't deallocate your
BSTR members using whatever functions you need.
If not I may not be able to use this
because the vector undergoes erasure/insertion during the lifetime of
my application and during such erasure I want to be able to free up
the BSTRs memory allocated inside every instance of MyStruct. IOW I
have engineered a situation where the capacity of the vector remains
intact -- its just its size() that contracts & expands.


The bottom line: if you have resource acquisition/dismissal during
exectuion of your program, you need to leave it to creation/destruction
of objects. RAII is one of the cornerstones of proper OOP.

As to COM implications, please ask in a Microsoft newsgroup. I am not
certain what you can or cannot do, and this is not the right place to
discsuss it.
V
--
Please remove capital As from my address when replying by mail
Apr 26 '06 #6
Victor Bazarov wrote:
Dilip wrote:
[..]
Apologies for the silly question but I presume vector.erase will call
dtor of the contained objects?
That is correct. How does it help you? Your MyStruct has no d-tor,
and the one that the compiler creates for you won't deallocate your
BSTR members using whatever functions you need.


I know what a compiler generated dtor can and cannot do unless I put in
my own code to deallocate/allocate whatever I want to. That was not my
question -- I was simply trying to confirm calling vector.erase does
indeed call the dtor of the contained objects.
If not I may not be able to use this
because the vector undergoes erasure/insertion during the lifetime of
my application and during such erasure I want to be able to free up
the BSTRs memory allocated inside every instance of MyStruct. IOW I
have engineered a situation where the capacity of the vector remains
intact -- its just its size() that contracts & expands.


The bottom line: if you have resource acquisition/dismissal during
exectuion of your program, you need to leave it to creation/destruction
of objects. RAII is one of the cornerstones of proper OOP.


I know that -- the reason why I posted this question in the first place
was because I couldn't follow proper OOP idiom here and hence was
looking for a clever way to use some STL algorithm I have never ran
into so far to delete memory allocated by the members of MyStruct _and_
erase the individual instances. IOW, I was looking for a better way
than the for_each/vector.erase combination.
As to COM implications, please ask in a Microsoft newsgroup. I am not
certain what you can or cannot do, and this is not the right place to
discsuss it.


I brought up COM only to explain what a BSTR was. My question was and
still remains a C++ question.

Apr 27 '06 #7
Alf P. Steinbach wrote:
That will be hugely inefficient when a MyStruct is copied within the
vector, as happens e.g. when the vector reallocates.

One slightly less inefficient way could be to use boost::shared_ptr to
encapsulate a BSTR (the BSTR type is a pointer).

But, personally I'd encapsulate that vector in a class, because it's
evidently an implementation of something with a very restricted set of
operations, and use an ordinary for loop in the class' destructor.


My only concern in starting this thread was to find out whether a
for_each and a vector.erase might turn out to be inefficient as the
calls completely traverse the vector 2 times.

As a side note, a vector re-allocation cannot happen in my system
because I have locked the capacity at a pre-determined limit and knock
off the elements once that limit is hit.

Unfortunately I can't use Boost :-(

Apr 27 '06 #8
Dilip wrote:
Victor Bazarov wrote:

struct MyStruct
{
BSTR somestring;
BSTR someotherstring;
};

vector<MyStruct> my_struct;


See, the problem is I simplified this struct a little too much. This
struct gets used across COM boundaries so I have to put it in a IDL
file and once I do that I don't think I can start adding ctors/dtors
and other stuff.


You will save a lot of headaches by not using this struct
anywhere, except in COM interface calls. If you need to
manipulate this data yourself, define your own struct, eg:
struct ProperStruct { std::wstring some, someother; }
and include a functions to convert between a ProperStruct
and a MyStruct when it comes time to make an interface call.

I recommend this strategy for deleting strings: maintain a
separate container of all your BSTRs. When you've finished
with your vector, just destroy the vector normally. Then go
through the separate container and SysFreeString all of them.

Apr 27 '06 #9
Old Wolf wrote:
I recommend this strategy for deleting strings: maintain a
separate container of all your BSTRs.
Let me add that this is only if you decide to stick with the
idea of using a vector of structs of BSTR. My preferred
solution is to work with structs of CComBSTR, or
some other string type; and then generate a struct of BSTR
only when it's needed for a COM interface call; it makes
all of this management crap unnecessary.
When you've finished
with your vector, just destroy the vector normally. Then go
through the separate container and SysFreeString all of them.


Something like this:

struct BstrManager
{
~BstrManager() { clear(); }
void clear()
{
for_each(all.begin(), all.end(), SysFreeString);
all.clear();
}
BSTR createString(wchar_t const *s, size_t len)
{
BSTR b = SysAllocStringLen(s, len);
all.push_back(b);
return b;
}
BSTR copyString( BSTR s )
{
BSTR b = SysAllocString(s);
all.push_back(b);
return b;
}
void deleteString( BSTR b )
{
std::vector<BSTR>::iterator it = all.find(b);
if ( it != all.end() ) { SysFreeString(b); all.erase(it); }
}

private:
std::vector<BSTR> all;
};

Then in your code you can go:
MyStruct m;
m.somestring = manager.createString(L"Hello", 5);
m.otherstring = manager.copyString(m.somestring);
vec.push_back(m);
// ......
vec.clear();
manager.clear();

Apr 27 '06 #10
Dilip wrote:
My only concern in starting this thread was to find out whether a
for_each and a vector.erase might turn out to be inefficient as the
calls completely traverse the vector 2 times.


Alternating between deleting a single BSTR and erasing a single element
from a vector is also inefficient. And if you erase an entire iterator
range, it's likely to be more efficient than looping yourself (cause
the
compiler can see it has to update size() only once, etc. )

HTH,
Michiel Salters

Apr 27 '06 #11
* Mi*************@tomtom.com:
Dilip wrote:
My only concern in starting this thread was to find out whether a
for_each and a vector.erase might turn out to be inefficient as the
calls completely traverse the vector 2 times.


Alternating between deleting a single BSTR and erasing a single element
from a vector is also inefficient. And if you erase an entire iterator
range, it's likely to be more efficient than looping yourself (cause
the
compiler can see it has to update size() only once, etc. )


Uh, well. It's potentially an O(n) operation as opposed to an O(n^2)
operation; the size() update is mostly irrelevant, I should think.
However, for this concrete case the most efficient is to never erase.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Apr 27 '06 #12

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

Similar topics

1
by: Nobody | last post by:
I've got a Binary Search Tree all completed, and now I am trying to derive an AVL Tree from it. I've got all the functions figured out except the removal. Haven't got a clue on an algorithm to do...
4
by: Tarique Jawed | last post by:
Alright I needed some help regarding a removal of a binary search tree. Yes its for a class, and yes I have tried working on it on my own, so no patronizing please. I have most of the code working,...
5
by: junky_fellow | last post by:
How do we calculate the complexity of an algorithm? Am i right if i say the complexity of an algorithm is the number of comparisons done in that algorithm? thanx in advance .......
12
by: No Such Luck | last post by:
Hi All: I'm not sure if this is the right place to ask this question, but I couldn't find a more appropriate group. This is more of a theory question regarding an algorithm implemented in C, not...
2
by: ben | last post by:
hello, i'm following an algorithm book and am stuck on an early excersise in it, not because of the c programming side of it or even the algorithm side of it, i don't think, but because of maths....
113
by: Bonj | last post by:
I was in need of an encryption algorithm to the following requirements: 1) Must be capable of encrypting strings to a byte array, and decyrpting back again to the same string 2) Must have the same...
5
by: raja | last post by:
Design and implement an efficient algorithm to remove consecutive 1char, 2char, 3 char... so on recurrences in dictionary words. For example, "abbabccbc" first will become "ababcbc", then become...
7
by: Dennis Yurichev | last post by:
Hello. I'm looking for any algorithm which can take C++ experssion at input and offer at output the same expression with excessive bracketts removed. Where should I look for it?
1
by: almurph | last post by:
Hi everyone, Concerning the Needleman-Wunsch algorithm (cf. http://en.wikipedia.org/wiki/Needleman-Wunsch_algorithm) I have noticed a possible loop. Inside the algorithm there is an...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

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.