By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,127 Members | 1,343 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,127 IT Pros & Developers. It's quick & easy.

is using tons of stl a correct method?

P: n/a
in a project, I use many,many stl such as stack,list,vctor etc.

somewhere the vector's size is more than 2K. is this a efficient way?
Jul 22 '05 #1
Share this Question
Share on Google+
25 Replies


P: n/a
rokia wrote:
in a project, I use many,many stl such as stack,list,vctor etc.

somewhere the vector's size is more than 2K. is this a efficient way?


Using robust Standard Library gizmos is infinitely more efficient, in terms
of programming time, than using raw arrays, linked lists, 'new', etc. If you
use those, you will endlessly reinvent low-level details that Standard
Library things, and risk bugs as you reinvent. Using STL containers makes
C++ as cognitively efficient as a "high-level" language.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces


Jul 22 '05 #2

P: n/a
Yes, I concur. I've recently been able to use STL exclusively rather
than C-arrays and home-brewed d/s, I've had very few crashes and
clean up is a breeze - its done for me! Thank you Alex Stepanov, you da
man!!

"Phlip" <ph*******@yahoo.com> wrote in message
news:NT*****************@newssvr31.news.prodigy.co m...
rokia wrote:
in a project, I use many,many stl such as stack,list,vctor etc.

somewhere the vector's size is more than 2K. is this a efficient way?
Using robust Standard Library gizmos is infinitely more efficient, in

terms of programming time, than using raw arrays, linked lists, 'new', etc. If you use those, you will endlessly reinvent low-level details that Standard
Library things, and risk bugs as you reinvent. Using STL containers makes
C++ as cognitively efficient as a "high-level" language.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces

Jul 22 '05 #3

P: n/a
thanks for your reply.

another question:

when you have a class A. will you push_back A to a list? or just the
pointer of A?

I mean which is the right one below:

1: class A;
list<A> la;
A a,b,c;
la.push_back(a); la.push_back(b),la.push_back(c);

2:class A;
list<A*> la;
A *pa;
A *pb;
A *pc;
la.push_back(pa);la.push_back(pb);la.push_back(pc) ;

and which method should I use If THERE ARE 5000 class A OR MORE?

thanks.:)

Jul 22 '05 #4

P: n/a
thanks.

and what does 'home-brewed d/s' mean ?

"Dave Townsend" <da********@comcast.net> 写入邮件
news:4K********************@comcast.com...
Yes, I concur. I've recently been able to use STL exclusively rather
than C-arrays and home-brewed d/s, I've had very few crashes and
clean up is a breeze - its done for me! Thank you Alex Stepanov, you da
man!!

"Phlip" <ph*******@yahoo.com> wrote in message
news:NT*****************@newssvr31.news.prodigy.co m...
rokia wrote:
in a project, I use many,many stl such as stack,list,vctor etc.

somewhere the vector's size is more than 2K. is this a efficient way?


Using robust Standard Library gizmos is infinitely more efficient, in

terms
of programming time, than using raw arrays, linked lists, 'new', etc. If

you
use those, you will endlessly reinvent low-level details that Standard
Library things, and risk bugs as you reinvent. Using STL containers makes C++ as cognitively efficient as a "high-level" language.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces


Jul 22 '05 #5

P: n/a

I meant adhoc development of data structures (d/s).
"rokia" <ro*****@yahoo.com.cn.discuss> wrote in message
news:ce***********@mail.cn99.com...
thanks.

and what does 'home-brewed d/s' mean ?

"Dave Townsend" <da********@comcast.net> 写入邮件
news:4K********************@comcast.com...
Yes, I concur. I've recently been able to use STL exclusively rather
than C-arrays and home-brewed d/s, I've had very few crashes and
clean up is a breeze - its done for me! Thank you Alex Stepanov, you da
man!!

"Phlip" <ph*******@yahoo.com> wrote in message
news:NT*****************@newssvr31.news.prodigy.co m...
rokia wrote:

> in a project, I use many,many stl such as stack,list,vctor etc.
>
> somewhere the vector's size is more than 2K. is this a efficient way?
Using robust Standard Library gizmos is infinitely more efficient, in

terms
of programming time, than using raw arrays, linked lists, 'new', etc.
If you
use those, you will endlessly reinvent low-level details that Standard
Library things, and risk bugs as you reinvent. Using STL containers

makes C++ as cognitively efficient as a "high-level" language.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces



Jul 22 '05 #6

P: n/a
STL containers work by making copies of objects, so push_back(a)
makes a copy of a in the container. When you access a, say by
vector at(), it gives you a copy of the object. Make sure that
you have the appropriate constructors implemented however, otherwise
you'll end up with garbage...

You can also store pointers in the STL container, but you have
to declare the container as a container of pointers, ie, list<A*> rather
than list<A>
"rokia" <ro*****@yahoo.com.cn.discuss> wrote in message
news:ce***********@mail.cn99.com...
thanks for your reply.

another question:

when you have a class A. will you push_back A to a list? or just the
pointer of A?

I mean which is the right one below:

1: class A;
list<A> la;
A a,b,c;
la.push_back(a); la.push_back(b),la.push_back(c);

2:class A;
list<A*> la;
A *pa;
A *pb;
A *pc;
la.push_back(pa);la.push_back(pb);la.push_back(pc) ;

and which method should I use If THERE ARE 5000 class A OR MORE?

thanks.:)

Jul 22 '05 #7

P: n/a
yeah, I know this.

I want to know which way is the better one?

"Dave Townsend" <da********@comcast.net> 写入邮件
news:96********************@comcast.com...
STL containers work by making copies of objects, so push_back(a)
makes a copy of a in the container. When you access a, say by
vector at(), it gives you a copy of the object. Make sure that
you have the appropriate constructors implemented however, otherwise
you'll end up with garbage...

You can also store pointers in the STL container, but you have
to declare the container as a container of pointers, ie, list<A*> rather
than list<A>
"rokia" <ro*****@yahoo.com.cn.discuss> wrote in message
news:ce***********@mail.cn99.com...
thanks for your reply.

another question:

when you have a class A. will you push_back A to a list? or just the
pointer of A?

I mean which is the right one below:

1: class A;
list<A> la;
A a,b,c;
la.push_back(a); la.push_back(b),la.push_back(c);

2:class A;
list<A*> la;
A *pa;
A *pb;
A *pc;
la.push_back(pa);la.push_back(pb);la.push_back(pc) ;

and which method should I use If THERE ARE 5000 class A OR MORE?

thanks.:)


Jul 22 '05 #8

P: n/a
rokia wrote:
another question:

when you have a class A. will you push_back A to a list? or just the
pointer of A?


If A can have derived classes, push a shared pointer (such as the smart
pointers at www.boost.org).

If A can't have derived classes, push it in by copy.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #9

P: n/a
[top-post fixed - please take pride in your posts and clean each one]

Dave Townsend wrote:
STL containers work by making copies of objects, so push_back(a)
makes a copy of a in the container. When you access a, say by
vector at(), it gives you a copy of the object. Make sure that
you have the appropriate constructors implemented however, otherwise
you'll end up with garbage...

You can also store pointers in the STL container, but you have
to declare the container as a container of pointers, ie, list<A*> rather
than list<A>
rokia wrote:
yeah, I know this.

I want to know which way is the better one?


Premature optimization is the root of all evil. STL wouldn't exist if it
weren't as fast as the alternative (raw arrays for std::vector, raw linked
lists for std::list, etc.).

What you gain by using STL is clean interfaces that are very easy to use
right and frequently hard to use wrong. That frees your time up to
concentrate on program logic.

The most important resource to optimize is programmer time. If you write
clean code (and unit tests on each feature), you will have time to then
profile your code and see if it really is slow. The odds are very good that
your code will perform acceptably with obvious implementations.
and which method should I use If THERE ARE 5000 class A OR MORE?


The only only only way to tell is put 5,000 class A objects in and see.
Different STLs have different performance profiles, but many other aspects
of your code, even the vaguarities of your CPU cache and pipelining, can
affect performance.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #10

P: n/a
rokia wrote:
and what does 'home-brewed d/s' mean ?


Data structures.

(Give Dave a break - typing the extra several letters would have doubtless
pushed him over his edge.. ;)

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #11

P: n/a
On Mon, 26 Jul 2004 13:19:42 +0800, rokia <ro*****@yahoo.com.cn.discuss>
wrote:
yeah, I know this.

I want to know which way is the better one?


Well of course it depends on what you want to do.

But certainly I would avoid pointers most of the time. And even when I
wanted pointers I would usually use smart pointers not raw pointers.

john
Jul 22 '05 #12

P: n/a
sorry for my poor english.

I didn't got what you do mean.

can you give me a simple answer?

Yes or NO?
Should I use list<A> or List<A*> ??
Jul 22 '05 #13

P: n/a
Thanks A lot! :)

"Phlip" <ph*******@yahoo.com> 写入邮件
news:6N************@newssvr33.news.prodigy.com...
[top-post fixed - please take pride in your posts and clean each one]

Dave Townsend wrote:
STL containers work by making copies of objects, so push_back(a)
makes a copy of a in the container. When you access a, say by
vector at(), it gives you a copy of the object. Make sure that
you have the appropriate constructors implemented however, otherwise
you'll end up with garbage...

You can also store pointers in the STL container, but you have
to declare the container as a container of pointers, ie, list<A*> rather than list<A>
rokia wrote:
yeah, I know this.

I want to know which way is the better one?
Premature optimization is the root of all evil. STL wouldn't exist if it
weren't as fast as the alternative (raw arrays for std::vector, raw linked
lists for std::list, etc.).

What you gain by using STL is clean interfaces that are very easy to use
right and frequently hard to use wrong. That frees your time up to
concentrate on program logic.

The most important resource to optimize is programmer time. If you write
clean code (and unit tests on each feature), you will have time to then
profile your code and see if it really is slow. The odds are very good

that your code will perform acceptably with obvious implementations.
and which method should I use If THERE ARE 5000 class A OR MORE?


The only only only way to tell is put 5,000 class A objects in and see.
Different STLs have different performance profiles, but many other aspects
of your code, even the vaguarities of your CPU cache and pipelining, can
affect performance.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces

Jul 22 '05 #14

P: n/a
[snips]

On Mon, 26 Jul 2004 05:38:10 +0000, Phlip wrote:
Premature optimization is the root of all evil. STL wouldn't exist if it
weren't as fast as the alternative (raw arrays for std::vector,


Simple local testing reveals that inserting objects into a vector via
push_back is approximately 8 times slower than simply storing them into an
array and a simple loop and increment ( for i = 0 to nelems; inc elem )
runs a good three times slower with vectors.

Speed isn't the key to the STL. The fact that it provides reasonable
speed, plus a very rich set of operations and relieves the coder from
managing all the gory details seems a little more significant.
Jul 22 '05 #15

P: n/a
Kelsey Bjarnason wrote:
Phlip wrote:
Premature optimization is the root of all evil. STL wouldn't exist if it
weren't as fast as the alternative (raw arrays for std::vector,
Simple local testing reveals that inserting objects into a vector via
push_back is approximately 8 times slower than simply storing them into an
array and a simple loop and increment ( for i = 0 to nelems; inc elem )
runs a good three times slower with vectors.


Set the capacity first. That's cognitively the same thing you do with a
fixed-size array. You compared a vector to calling new over and over again.
Speed isn't the key to the STL. The fact that it provides reasonable
speed, plus a very rich set of operations and relieves the coder from
managing all the gory details seems a little more significant.


Speed is the key. Vendors may implement containers however they see fit, but
each container type has a performance profile guaranteed to match an
equivalent "manual" data structure. vector iterates as quickly as an array,
and accesses randomly as quickly as an array. list can delete a middle
element as quickly as a linked list can pull out an inner node. Etc.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #16

P: n/a
"Phlip" <ph*******@yahoo.com> wrote in message news:<Bs****************@newssvr17.news.prodigy.co m>...
Kelsey Bjarnason wrote:
Phlip wrote:
Premature optimization is the root of all evil. STL wouldn't exist if it
weren't as fast as the alternative (raw arrays for std::vector,


Simple local testing reveals that inserting objects into a vector via
push_back is approximately 8 times slower than simply storing them into an
array and a simple loop and increment ( for i = 0 to nelems; inc elem )
runs a good three times slower with vectors.


Set the capacity first. That's cognitively the same thing you do with a
fixed-size array. You compared a vector to calling new over and over again.
Speed isn't the key to the STL. The fact that it provides reasonable
speed, plus a very rich set of operations and relieves the coder from
managing all the gory details seems a little more significant.


Speed is the key. Vendors may implement containers however they see fit, but
each container type has a performance profile guaranteed to match an
equivalent "manual" data structure. vector iterates as quickly as an array,
and accesses randomly as quickly as an array. list can delete a middle
element as quickly as a linked list can pull out an inner node. Etc.

--
Phlip


Hi guys. I read this thread with interest. I program as a hobby and
migrated to C++ from BASIC about 2 yrs ago and have been wondering
about using STL. I find myself using arrays rather than vectors even
when I need to put the data on the heap, although I don't advocate
others do the same...for me it just seems simpler. As an example of
where I do this, I have a data-holding class that over-writes the
memory (for security reasons, using memset()) in the destructor before
releasing the memory. When I was designing the class, I couldn't
think of an easy way to get a vector to do the same. Does this
particular requirement (that no data remains in ram once it is
released) necessitate the use of arrays, or can the same be achieved
using vectors?

The data size is unknown at compile time, so the class goes through
the rigmarole of newing and deleting itself upon initiation, copy, and
destruction.

Thanks for this helpful thread.
Jul 22 '05 #17

P: n/a
As an example of
where I do this, I have a data-holding class that over-writes the
memory (for security reasons, using memset()) in the destructor before
releasing the memory. When I was designing the class, I couldn't
think of an easy way to get a vector to do the same. Does this
particular requirement (that no data remains in ram once it is
released) necessitate the use of arrays, or can the same be achieved
using vectors?


Assuming your vector is called vec

memset(&vec[0], 0, vec.size()*sizeof vec[0]);

The trick is that &vec[0] can be used to get the address of the first vector
element (and also that the C++ standard guarantees that a vector elements
occupy contiguous memory).

john
Jul 22 '05 #18

P: n/a

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2m************@uni-berlin.de...
As an example of
where I do this, I have a data-holding class that over-writes the
memory (for security reasons, using memset()) in the destructor before
releasing the memory. When I was designing the class, I couldn't
think of an easy way to get a vector to do the same. Does this
particular requirement (that no data remains in ram once it is
released) necessitate the use of arrays, or can the same be achieved
using vectors?
Assuming your vector is called vec

memset(&vec[0], 0, vec.size()*sizeof vec[0]);

The trick is that &vec[0] can be used to get the address of the first

vector element (and also that the C++ standard guarantees that a vector elements
occupy contiguous memory).

john


Thanks John. What about if the vector reallocates itself (ie the data is
concatinable)? Is there a way to make certain that the pre-reallocated
vector is over-written?

Thanks for the reply.

Joe
Jul 22 '05 #19

P: n/a
Joe C wrote:
"John Harrison" <jo*************@hotmail.com> wrote in message
news:2m************@uni-berlin.de...
As an example of
where I do this, I have a data-holding class that over-writes the
memory (for security reasons, using memset()) in the destructor before
releasing the memory. When I was designing the class, I couldn't
think of an easy way to get a vector to do the same. Does this
particular requirement (that no data remains in ram once it is
released) necessitate the use of arrays, or can the same be achieved
using vectors?


Assuming your vector is called vec

memset(&vec[0], 0, vec.size()*sizeof vec[0]);

The trick is that &vec[0] can be used to get the address of the first


vector
element (and also that the C++ standard guarantees that a vector elements
occupy contiguous memory).


Thanks John. What about if the vector reallocates itself (ie the data is
concatinable)? Is there a way to make certain that the pre-reallocated
vector is over-written?


You could use std::vector::reserve() to prevent reallocations. Or you
could use a different allocator with the vector; one that clears memory
before deallocating it. Such an allocator could also be used with other
container classes.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
Jul 22 '05 #20

P: n/a
Peter van Merkerk wrote:
Joe C wrote:

Thanks John. What about if the vector reallocates itself (ie the data is
concatinable)? Is there a way to make certain that the pre-reallocated
vector is over-written?


You could use std::vector::reserve() to prevent reallocations. Or you
could use a different allocator with the vector; one that clears memory
before deallocating it. Such an allocator could also be used with other
container classes.


You might find this an interesting read:
http://eddeye.net/src/secalloc/secalloc.pdf

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
Jul 22 '05 #21

P: n/a
"rokia" <ro*****@yahoo.com.cn.discuss> wrote in message news:<ce***********@mail.cn99.com>...
in a project, I use many,many stl such as stack,list,vctor etc.

somewhere the vector's size is more than 2K. is this a efficient way?


A number like 2K is nearly meaningless by itself. Using 2K to store 80
bytes of information is a whole different story from using 2K to store
1.9K of information.

In the end, std::vector inevitably impose some overhead: if I'm not
mistaken, it's typically implemented as a small data structure
containing a few fixed items (e.g. the currently allocated size, the
current number of items in use) and a pointer to the actual data,
which is normally allocated from the free store. The size allocated
on the free store varies geometrically if you allow it to grow by
default. This limits wasted space to a specific percentage. In
addition, when/if you remove items from the vector, its size normally
does NOT shrink automatically, so if you erase a great deal from the
vector, its overhead can be quite high until/unless you shrink it back
down manually.

Ultimately, the standard library is intended to be useful across a
wide variety of situations. To accomplish that, it cannot concentrate
solely on minimizing memory usage. Rather, it has to balance memory
usage with CPU usage. In most cases, if there's a conflict between the
two, the current specification tends to favor the latter.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 22 '05 #22

P: n/a
Thanks for your explanation.
"Jerry Coffin" <jc*****@taeus.com> ????
news:b2************************@posting.google.com ...
"rokia" <ro*****@yahoo.com.cn.discuss> wrote in message

news:<ce***********@mail.cn99.com>...
in a project, I use many,many stl such as stack,list,vctor etc.

somewhere the vector's size is more than 2K. is this a efficient way?


A number like 2K is nearly meaningless by itself. Using 2K to store 80
bytes of information is a whole different story from using 2K to store
1.9K of information.

In the end, std::vector inevitably impose some overhead: if I'm not
mistaken, it's typically implemented as a small data structure
containing a few fixed items (e.g. the currently allocated size, the
current number of items in use) and a pointer to the actual data,
which is normally allocated from the free store. The size allocated
on the free store varies geometrically if you allow it to grow by
default. This limits wasted space to a specific percentage. In
addition, when/if you remove items from the vector, its size normally
does NOT shrink automatically, so if you erase a great deal from the
vector, its overhead can be quite high until/unless you shrink it back
down manually.

Ultimately, the standard library is intended to be useful across a
wide variety of situations. To accomplish that, it cannot concentrate
solely on minimizing memory usage. Rather, it has to balance memory
usage with CPU usage. In most cases, if there's a conflict between the
two, the current specification tends to favor the latter.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 22 '05 #23

P: n/a
On Mon, 26 Jul 2004 12:00:25 -0400, "Joe C" <jk*****@bellsouth.net>
wrote:

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2m************@uni-berlin.de...
> As an example of
> where I do this, I have a data-holding class that over-writes the
> memory (for security reasons, using memset()) in the destructor before
> releasing the memory. When I was designing the class, I couldn't
> think of an easy way to get a vector to do the same. Does this
> particular requirement (that no data remains in ram once it is
> released) necessitate the use of arrays, or can the same be achieved
> using vectors?


Assuming your vector is called vec

memset(&vec[0], 0, vec.size()*sizeof vec[0]);

The trick is that &vec[0] can be used to get the address of the first

vector
element (and also that the C++ standard guarantees that a vector elements
occupy contiguous memory).

john


Thanks John. What about if the vector reallocates itself (ie the data is
concatinable)? Is there a way to make certain that the pre-reallocated
vector is over-written?


The best thing would be to write your own allocator. The you can do
the memset in the deallocate function, and then there's no risk of
those precious bytes hanging around when you don't want them to,
regardless of the container you're using.

Tom
Jul 22 '05 #24

P: n/a
Peter van Merkerk <me*****@deadspam.com> wrote in message news:<2m************@uni-berlin.de>...
Peter van Merkerk wrote:
Joe C wrote:

Thanks John. What about if the vector reallocates itself (ie the data is
concatinable)? Is there a way to make certain that the pre-reallocated
vector is over-written?


You could use std::vector::reserve() to prevent reallocations. Or you
could use a different allocator with the vector; one that clears memory
before deallocating it. Such an allocator could also be used with other
container classes.


You might find this an interesting read:
http://eddeye.net/src/secalloc/secalloc.pdf

Thanks Peter for the replies. These authors address the same issues I
was attempting to deal with. My understanding of the STL is too weak
to follow the advice for writing my own allocators for use with the
STL. My AlignInt class takes a file, string, or another class object
to initialize. The data is word-aligned in memory so that
word-oriented operations are guaranteed to work on the data, however a
pointer to the data as bytes is also offered to the class user. data
may be concatinated and assigned, and the class can return it's data
(or a subset of it's data) as a string. I realize that a weakness of
my approach is that it gives direct (public) access to the memory. I
chose to do things this way because I was writing the the class to
support a specific application, not as a general-use container.
However, I've now opted to use the container in several other
projects. I would love receive criticism/comments on how to
better-implement a data-container with these properties. I have
attached the declaration/implementation of the current iteration of my
container. I appologize that I didn't write/edit the code to make it
easy to read on the news-reader. Also...it may not be clear why I
have some particular functions in the class...they were all written to
address specific issues for a particular program, and it is likely
that better, more general solutions exist, which is why I post.

begin------->Align_int_class.h

// Class to put data on the heap and forces the data to be aligned
// with native words...then offer pointers to that data as either
native
// integer or byte. Class overwrites data before releasing so that
data
// does not linger in memory.

// I've tried to keep this class light, but have freely added methods
as/when it's
// been convenient.
#ifndef ALIGNINT
#define ALIGNINT

#include <string>
#include <stdint.h>

class AlignInt{
private:
bool haveMemory;
unsigned int wordsize;

public:
unsigned int len_c; // len of memory in bytes (char)
unsigned int len_l; // len of memory in words (long)
uint32_t* ul; // points to memory
char* c; // points to same memory

// Constructors
AlignInt(); // default constructor...uninitialized pointer
AlignInt(int byte_len); // new empty with space reserved =
byte_len
AlignInt(uint32_t* parray, unsigned int byte_len); // new
object points to preexisting memory. memory must be freed elsewhere
AlignInt(const std::string& stringin); // copy string to new
properly sized AlignInt object

// Copy Constructors
AlignInt(const AlignInt& rhs); //copy
constructor
AlignInt(const AlignInt& rhs1, const AlignInt& rhs2);
//overloaded copy constructor..concatinates 2 objects

// Overloaded operator
AlignInt operator=(const AlignInt&); // assign AlignInt
to AlignInt
AlignInt operator=(const std::string& rhs); // assign string
to AlignInt
AlignInt operator+(const AlignInt& rhs); // concatinate

// Destructor
~AlignInt(); // clears mem on
close

// Other Methods
void loadfile(const std::string& filespec); // puts file
into object
bool hasData(){return haveMemory;} // has 'new'
been called by this object? If yes, clear memory upon destruction.
void clearend(); // since data is
'int-aligned' there may be trailing bytes that are not part of the
real data. This function clears them.
std::string str(); // returns data
as new std::string
std::string str(int offset, int chars_to_get);// similar to
std::string.substr()
void resizeEmpty(int byte_len); // erases old
data and makes a new resized
};

#endif //ALIGNINT

end------->Align_int_class.h

begin------->Align_int_class.cpp

#include "align_int_class.h"
#include "file_ok.h"

#include <iostream>
#include <fstream>

using namespace std;
//constructors
// default new empty
AlignInt::AlignInt()
:
haveMemory(false)
,wordsize(sizeof(*ul))
,len_c(0)
,len_l(0)
,ul(NULL)
,c(NULL)
{}

// new empty of defined length
AlignInt::AlignInt(int byte_len)
:
haveMemory(true)
,wordsize(sizeof(*ul))
,len_c(byte_len)
,len_l((len_c / wordsize) + ((len_c % wordsize) > 0))
,ul(new uint32_t[len_l])
,c(reinterpret_cast<char*>(ul))
{
memset(c, 0, len_l * wordsize );
}

//prealigned memory must be deallocated elsewhere
AlignInt::AlignInt(uint32_t* parray, unsigned int byte_len)
:
haveMemory(false)
,wordsize(sizeof(*ul))
,len_c(byte_len)
,len_l((len_c / wordsize) + ((len_c % wordsize) > 0))
,ul(parray)
,c(reinterpret_cast<char*>(ul))
{
clearend();
}

AlignInt::AlignInt(const string& stringin) // copy string
:
haveMemory(true)
,wordsize(sizeof(*ul))
,len_c(stringin.size())
,len_l((len_c / wordsize) + ((len_c % wordsize) > 0))
,ul(new uint32_t[len_l])
,c(reinterpret_cast<char*>(ul))
{

for(unsigned int j = 0; j < len_c; ++j){
c[j] = stringin[j];
}
clearend();
}

// Copy Constructors
AlignInt::AlignInt(const AlignInt& rhs) //copy constructor
:
haveMemory(true)
,wordsize(sizeof(*ul))
,len_c(rhs.len_c)
,len_l(rhs.len_l)
,ul(new uint32_t[rhs.len_l])
,c(reinterpret_cast<char*>(ul))
{
memcpy(c, rhs.c, rhs.len_c);
clearend();
}

AlignInt::AlignInt(const AlignInt& rhs1, const AlignInt& rhs2)
//overloaded copy-constructor, used to concatinate
:
haveMemory(true)
,wordsize(sizeof(*ul))
,len_c(rhs1.len_c + rhs2.len_c)
,len_l((len_c / wordsize) + ((len_c % wordsize) > 0))
,ul(new uint32_t[len_l])
,c(reinterpret_cast<char*>(ul))
{
memcpy(c, rhs1.c, rhs1.len_c);
memcpy((c + rhs1.len_c), rhs2.c, rhs2.len_c);
clearend();
}

// Assignment operator
AlignInt AlignInt::operator=(const AlignInt& rhs){
if(this != &rhs){
if(haveMemory){ //indicated memory has been allocated
memset(c, 0, len_l * wordsize);
delete[] ul;
}
len_c = rhs.len_c;
len_l = rhs.len_l;
ul = new uint32_t[rhs.len_l];
c = reinterpret_cast<char*>(ul);
haveMemory = true;
wordsize = sizeof(*ul);
memcpy(c, rhs.c, len_c);
clearend();
}
return *this;
}

AlignInt AlignInt::operator=(const string& rhs){

if(haveMemory){ //indicated memory has been allocated
memset(c, 0, len_l * wordsize);
delete[] ul;
}
len_c = rhs.size();
len_l = (len_c / wordsize) + ((len_c % wordsize) > 0);
ul = new uint32_t[len_l];
c = reinterpret_cast<char*>(ul);
haveMemory = true;
wordsize = sizeof(*ul);
for(unsigned int i = 0; i < len_c; ++i){
c[i] = rhs[i];
}
clearend();
return *this;
}

AlignInt AlignInt::operator+(const AlignInt& rhs){
AlignInt temp(this->len_c + rhs.len_c);
memcpy(temp.c, this->c, this->len_c);
memcpy(temp.c + this->len_c, rhs.c, rhs.len_c);
temp.clearend();
return temp;
}

// Destructors
AlignInt::~AlignInt(){
if(haveMemory){
memset(c, 0, len_l * wordsize);
delete[] ul;
}
}

void AlignInt::loadfile(const string& filespec){
if(haveMemory){
cout << "ERROR...memory redesignation ERROR 1" << endl;
}else{
haveMemory = fileOK(filespec);
if(haveMemory){
ifstream in (filespec.c_str(), ios::in | ios::binary);
in.seekg(0, ios::end);
len_c = in.tellg(); // file length in bytes
len_l = (len_c / wordsize) + ((len_c % wordsize) > 0);
//^^^adds one if remainder^^^//
ul = new uint32_t[len_l];
ul[len_l - 1] = 0; // clear last word
c = reinterpret_cast<char*>(ul);
in.seekg(0, ios::beg);
in.read(c, (len_c));
in.close();
}else cout << "FILE ERROR: Cannot load: " << filespec << endl;
}
}

void AlignInt::clearend(){
memset(c + len_c, 0, (len_l * wordsize) - len_c);
}

string AlignInt::str(){
return string(c, len_c);
}

string AlignInt::str(int offset, int chars_to_get){
return string(c + offset, chars_to_get);
}

void AlignInt::resizeEmpty(int byte_len){
if(haveMemory){
memset(c, 0, len_l * wordsize);
delete[] ul;
}
haveMemory = true;
len_c = byte_len;
len_l = (len_c / wordsize) + ((len_c % wordsize) > 0);
ul = new uint32_t[len_l];
c = reinterpret_cast<char*>(ul);
memset(c, 0, len_l * wordsize);
}

end------->Align_int_class.cpp
Jul 22 '05 #25

P: n/a
J. Campbell wrote:
Peter van Merkerk <me*****@deadspam.com> wrote in message news:<2m************@uni-berlin.de>...
You might find this an interesting read:
http://eddeye.net/src/secalloc/secalloc.pdf
Thanks Peter for the replies. These authors address the same issues I
was attempting to deal with. My understanding of the STL is too weak
to follow the advice for writing my own allocators for use with the
STL.


I'm not exactly a STL or template guru myself, but time spend learning
and understanding the standard container classes is time well spend. The
authors of that article were quite ambitious. But if you take away the
policy stuff and settle for simply clearing memory before deallocation
it becomes a lot simpler:

#include <vector>
#include <memory>
#include <cstring>
template <typename T,
typename BASE = std::allocator<T>

class SecureAllocator : public BASE
{
public:
typedef typename BASE::pointer pointer;
typedef typename BASE::size_type size_type;

void deallocate(pointer p, size_type n)
{
// Fill memory with zero's before releasing it.
memset(p, 0, n * sizeof(T));
return BASE::deallocate(p, n);
}

template<typename U>
struct rebind {
typedef SecureAllocator<U> other;
};
};

typedef std::vector<int, SecureAllocator<int> > SecureIntVector;
int main()
{
SecureIntVector sv;

// Every time when the vector need to reallocate its
// buffer to accomodate new elements, the old buffer
// will be filled with zero's before is it deallocated.
for(int i = 0; i < 100; ++i)
{
sv.push_back(i);
}

// When the vector is destroyed the memory for the
// elements will be with zero's before is it deallocated.
}

The SecureAllocator should work with other container classes too. As far
as commenting your AlignInt class...keep in mind when reading from files
typically buffers are created behind your back which may hold part of
the file. Chances are that the buffers are *not* cleared before they are
deallocated.

There are probably many more things that could be said about the
AlignInt class...sorry, maybe some other time.

Regards

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
Jul 22 '05 #26

This discussion thread is closed

Replies have been disabled for this discussion.