473,406 Members | 2,769 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,406 software developers and data experts.

Smart pointer for arrays of structs?

Hi,

I have some data which is stored as plain old C structures. Until now I've
had arrays of these structs on stack but due to stack overrun I need to move
these to heap.
I've been trying out some smart pointers to help but so far the
implementation I've been dealing with has had problems with [] operator
since it could conflict when using the same class with "unsigned char".

Do you have any recommendations for smart pointers able to work with arrays?

I would need something like:

ptr = (new or malloc) MY_STRUCT [16];

ptr[i].member

Thanks.

-- Henrik
Dec 26 '06 #1
12 5171
Henrik Goldman wrote:
Hi,

I have some data which is stored as plain old C structures. Until now I've
had arrays of these structs on stack but due to stack overrun I need to move
these to heap.
I've been trying out some smart pointers to help but so far the
implementation I've been dealing with has had problems with [] operator
since it could conflict when using the same class with "unsigned char".

Do you have any recommendations for smart pointers able to work with arrays?

I would need something like:

ptr = (new or malloc) MY_STRUCT [16];

ptr[i].member
What is wrong with std::vector ?
Dec 26 '06 #2
>
What is wrong with std::vector ?
I forgot to mention that it's a requirement that the data needs to be
accessible from external C functions. For this reason it needs to be
serialized just like an ordinary array.

-- Henrik
Dec 26 '06 #3
"Henrik Goldman" <he************@mail.tele.dkwrote in message
news:45*********************@dread11.news.tele.dk. ..

What is wrong with std::vector ?

I forgot to mention that it's a requirement that the data needs to be
accessible from external C functions. For this reason it needs to be
serialized just like an ordinary array.

-- Henrik
std::vector fits the bill for that.
http://www.parashift.com/c++-faq-lit....html#faq-34.3
vector stores it's memory contiguous

Dec 26 '06 #4

Henrik Goldman wrote:

What is wrong with std::vector ?

I forgot to mention that it's a requirement that the data needs to be
accessible from external C functions. For this reason it needs to be
serialized just like an ordinary array.

-- Henrik
The std::vector is then perfect for the job. Not only are its elements
organized in contiguous memory and dynamic, its also much easier to
overload a global op<< to stream/serialize the data.

Show me code with a primitive array, and i'll show you a std::vector
that does the same but better, and then some. And that includes
performance.

Dec 26 '06 #5
Thank you Gianni, Jim, Peter, for your answers.

It seems to be a good choice. It certainly saved me from a day of work
trying to get a smart pointer class working to do the same job.

The way I use it is:

vector <mytypev;

v.resize(nElements);
and then
memset(&v[0], 0, sizeof(mytype) * v.size());

It's too bad I cannot do all the initialization at once. However the data
needs to be zero initialized and have a certain size. All in all it does
save me from some work so it's a cheap price to pay.

-- Henrik
Dec 26 '06 #6

Henrik Goldman wrote in message
<45*********************@dread11.news.tele.dk>.. .
>Thank you Gianni, Jim, Peter, for your answers.

It seems to be a good choice. It certainly saved me from a day of work
trying to get a smart pointer class working to do the same job.
The way I use it is:

vector <mytypev;

v.resize(nElements);
and then
memset(&v[0], 0, sizeof(mytype) * v.size());

It's too bad I cannot do all the initialization at once. However the data
needs to be zero initialized and have a certain size. All in all it does
save me from some work so it's a cheap price to pay.
--- Henrik
std::size_t nElements( 100 );
std::vector <mytypev( nElements, mytype(0) );

--
Bob R
POVrookie
Dec 26 '06 #7

Henrik Goldman wrote:
Thank you Gianni, Jim, Peter, for your answers.

It seems to be a good choice. It certainly saved me from a day of work
trying to get a smart pointer class working to do the same job.

The way I use it is:

vector <mytypev;

v.resize(nElements);
and then
memset(&v[0], 0, sizeof(mytype) * v.size());

It's too bad I cannot do all the initialization at once. However the data
needs to be zero initialized and have a certain size. All in all it does
save me from some work so it's a cheap price to pay.

-- Henrik
Oh yes you can. In more ways than one.
There is no need to use memset, let a ctor and copy-ctor do the work
for you.

#include <vector>

template< typename T >
class mytype
{
T t;
public:
mytype() : t() { }
mytype(const T& r_t) : t(r_t) { }
};

int main()
{
std::vector< mytype< double instance(1000); // same as
instance(1000, 0.0);
std::vector< mytype< double another(1000, 11.1);
std::vector< std::string vstrings(1000, "default string");
std::vector< int vn(1000, 99);
}

The first creates an instance of a std::vector with 1000 elements all
initialized to 0.0 (by def ctor)
The second initializes 1000 elements with a value of 11.1 (using
parametized ctor)
The third initializes 1000 std::strings with the same default.
The fourth has 1000 integers set to 99.

The only requirement is that the element-type be copyable and
assignable (op=). In the case involving the class above, mytype's
compiler-generated copy ctor and assignment operator fits the bill. In
the event your class doesn't have a compiler-generated ctor or op=,
make them.

Dec 26 '06 #8
Henrik Goldman wrote:
>What is wrong with std::vector ?

I forgot to mention that it's a requirement that the data needs to be
accessible from external C functions. For this reason it needs to be
serialized just like an ordinary array.
Again, what's wrong with std::vector? :)

std::vector<Tvec = ...;

extern "C" T *GetCArray()
{
return &vec.front();
}

--
Clark S. Cox III
cl*******@gmail.com
Dec 27 '06 #9

Henrik Goldman wrote:
>
vector <mytypev;

v.resize(nElements);
and then
memset(&v[0], 0, sizeof(mytype) * v.size());

It's too bad I cannot do all the initialization at once. However the data
needs to be zero initialized and have a certain size. All in all it does
save me from some work so it's a cheap price to pay.
If mytype is a class then its constructor will automatically be called.

If mytype is a C struct that needs to be used with C headers too (thus
you can't give it any constructors), then you can still do it using a
0-initialised element to constructor your vector or call resize. You
just have to create one such struct and use it to initialise all the
other members.

Note that you could use a "static" instance of one.

Beware, by the way, that &v[0] or &v.front() is undefined behaviour if
v is an empty vector, so you should check for this and probably return
a NULL pointer when that is the case.

Dec 27 '06 #10
If mytype is a C struct that needs to be used with C headers too (thus
you can't give it any constructors), then you can still do it using a
0-initialised element to constructor your vector or call resize. You
just have to create one such struct and use it to initialise all the
other members.
Yes in my case it's a C struct.
I don't really like your suggestion about using a preinitialized value
though. It requires even more code then other proposed solutions.
Note that you could use a "static" instance of one.
That is really not a good idea in my case since the code is used among
different projects and modules. It only makes it harder to understand.
Beware, by the way, that &v[0] or &v.front() is undefined behaviour if
v is an empty vector, so you should check for this and probably return
a NULL pointer when that is the case.
This is not the case for me fortunatly. In those places where I need it it
has been resize()'d in the constructor prior to any use.

Thanks.

-- Henrik
Dec 28 '06 #11

Henrik Goldman wrote:
Note that you could use a "static" instance of one.

That is really not a good idea in my case since the code is used among
different projects and modules. It only makes it harder to understand.
It doesn't really need to be static, a const global will do. It should
be initialised in one module though. Although globals are normally
evil, if it's const it is less evil.

const mytype zero_my_type = { 0, 0, 0, 0 }; // etc

then my_type_vec.resize( 50, zero_my_type );

If you prefer you can scope the instance and expose the function but
you really haven't gained a lot.
Beware, by the way, that &v[0] or &v.front() is undefined behaviour if
v is an empty vector, so you should check for this and probably return
a NULL pointer when that is the case.

This is not the case for me fortunatly. In those places where I need it it
has been resize()'d in the constructor prior to any use.
I have wrapper "buffer" classes that will wrap arrays or vectors and it
also has a begin() and end() which are guaranteed to be pointers. (I
have two such classes, one for const and one for non-const). buffer is
fairly trivial to write and looks something like this:

template < typename T >
class buffer
{
T * itsData;
size_t itsSize;
public:
buffer( T* d, size_t sz ) : itsData( d ), itsSize( sz ) {}

buffer( vector< T & vec )
: itsData( vec.empty() ? 0 : &vec[0] ),
itsSize( vec.size() )
{
}

buffer() : itsData( 0 ), itsSize( 0 )
{
}

buffer( T* first, T* last ) : itsData( first ), itsSize( last -
first )
{
}

T* begin() const { return itsData; }
T* end() const { return itsData + itsSize; }
bool empty() const { return itsSize == 0; }
size_t size() const { return itsSize; }
};

Define const_buffer exactly the same but with const T* pointers and
const std::vector<T& and add this constructor

const_buffer( const buffer<T& nc_buf ) : itsData( nc_buf.begin()
), itsSize( nc_buf.size() )
{
}

Note that these classes do not take ownership of the buffer so there is
no memory handling issue. You might be surprised that begin() and end()
are const methods even in buffer. They are because you cannot modify
the pointers themselves, only what they point to. The class is
non-mutable (cannot be changed) other than assigning it to another
instance. Note that its constructors that take one parameter are
purposely non-explicit.

Now with a vector that might be empty and passing it to a functino that
takes a pointer and size that might be empty you can always pass in

buffer( theVec ).begin() (or const_buffer( theVec ).begin() if
appropriate)

Dec 28 '06 #12
Henrik Goldman wrote:
Thank you Gianni, Jim, Peter, for your answers.

It seems to be a good choice. It certainly saved me from a day of work
trying to get a smart pointer class working to do the same job.

The way I use it is:

vector <mytypev;

v.resize(nElements);
and then
memset(&v[0], 0, sizeof(mytype) * v.size());

It's too bad I cannot do all the initialization at once. However the data
needs to be zero initialized and have a certain size.
static const mytype t;
vector<mytype v;
v.resize(nElements, t);
--
Clark S. Cox III
cl*******@gmail.com
Dec 28 '06 #13

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

Similar topics

9
by: christopher diggins | last post by:
I would like to survey how widespread the usage of smart pointers in C++ code is today. Any anecdotal experience about the frequency of usage of smart pointer for dynamic allocation in your own...
3
by: Vijai Kalyan | last post by:
I have been thinking about this and it may have already been thrashed out and hung out to dry as a topic of no more interest but here goes. I found when implementing a smart pointer that the...
10
by: Kieran Simkin | last post by:
Hi, I wonder if anyone can help me, I've been headscratching for a few hours over this. Basically, I've defined a struct called cache_object: struct cache_object { char hostname; char ipaddr;...
1
by: mrhicks | last post by:
Hello all, I need some advice/help on a particular problem I am having. I have a basic struct called "indv_rpt_rply" that holds information for a particular device in our system which I will...
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
8
by: Axter | last post by:
I normally use a program call Doxygen to document my source code.(http://www.stack.nl/~dimitri/doxygen) This method works great for small and medium size projects, and you can get good...
59
by: MotoK | last post by:
Hi Experts, I've just joined this group and want to know something: Is there something similar to smart pointers in C or something to prevent memory leakages in C programs. Regards MotoK
156
by: Lame Duck | last post by:
Hi Group! I have a vector<floatvariable that I need to pass to a function, but the function takes a float * arguement. That's OK, I can convert by doing &MyVector.front(), but when I get back a...
14
by: Szabolcs Borsanyi | last post by:
Deal all, The type typedef double ***tmp_tensor3; is meant to represent a three-dimensional array. For some reasons the standard array-of-array-of-array will not work in my case. Can I...
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: 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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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...
0
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...
0
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...
0
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,...
0
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...

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.