473,416 Members | 1,729 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,416 software developers and data experts.

memset on structs with non-PODs

Dear all,

I have an existing piece of code with a struct with some PODs.

struct A
{
int x;
int y;
};

This struct is created somewhere and initialized via a memset.

A a;
memset(&a,0,sizeof(A));

Now I want to extend the structure with an object, e.g a vector:

struct A
{
int x;
int y;
std::vector<int> z;
};

The sequence

A a;
memset(&a,0,sizeof(A));

would be fatal now, because I overwrite the instanciated vector a.z.
In reality the struct is very huge with a bunch of PODs inside, so using a
ctor would be possible, but quite a lot of work. (I am also scared to miss
something). How would you proceed to avoid the devastating memset?
I thought of kind of

struct A
{
int x;
int y;
int no_memsetbeyond_this_point;
std::vector<int> z;
};

and

A a;
memset(&a,0,&a.no_memsetbeyond_this_point-&a);

It is not really nice, but I have to avoid as much code-rework as possible
for the moment.

Kind regards,
Patrick
Jan 19 '06 #1
14 8305
* Patrick Kowalzick:
Dear all,

I have an existing piece of code with a struct with some PODs.

struct A
{
int x;
int y;
};

This struct is created somewhere and initialized via a memset.

A a;
memset(&a,0,sizeof(A));

Now I want to extend the structure with an object, e.g a vector:

struct A
{
int x;
int y;
std::vector<int> z;
};
When you have public non-POD members you need to redesign.

The sequence

A a;
memset(&a,0,sizeof(A));

would be fatal now, because I overwrite the instanciated vector a.z.
In reality the struct is very huge with a bunch of PODs inside, so using a
ctor would be possible, but quite a lot of work. (I am also scared to miss
something). How would you proceed to avoid the devastating memset?


When you a "very huge" struct you need to redesign.

But possibly you need to practice that on some smaller test programs
first.

For now, rename the orginal struct to PodA,

struct PodA { ... };

then derive struct A from that,

struct A: PodA
{
A(): PodA() {}
std::vector<int> z;
};

and also check that your compiler supports default-initialization of
POD's (unfortunately some don't).

--
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?
Jan 19 '06 #2
Hello Alf,
struct A
{
int x;
int y;
std::vector<int> z;
};
When you have public non-POD members you need to redesign.


Normally I'd never use struct for more complex things :).
In reality the struct is very huge with a bunch of PODs inside, so using
a
ctor would be possible, but quite a lot of work. (I am also scared to
miss
something). How would you proceed to avoid the devastating memset?


When you a "very huge" struct you need to redesign.


Hmm, might be. Lets say very huge in this context is nothing elses than: I
do not want to initialize all the members.
For now, rename the orginal struct to PodA,

struct PodA { ... };

then derive struct A from that,

struct A: PodA
{
A(): PodA() {}
std::vector<int> z;
};
Perfect. Thats a rather good solution. Anyway for this case I will change to

struct PodA
{
PodA() { memset(this,0,sizeof(PodA)); }
...
};

struct A: PodA
{
std::vector<int> z;
};

This is not nice (ok it is ugly), but closer to the original code.
and also check that your compiler supports default-initialization of
POD's (unfortunately some don't).


I can not, as support for different compiliers has to be assured.

Thanks, that's really good solution.

Regards,
Patrick
Jan 19 '06 #3
On Thu, 19 Jan 2006 14:57:34 +0100, "Patrick Kowalzick"
<pa***************@mapandguide.de> wrote:
Dear all,

I have an existing piece of code with a struct with some PODs.

struct A
{
int x;
int y;
};

This struct is created somewhere and initialized via a memset.

A a;
memset(&a,0,sizeof(A));

Now I want to extend the structure with an object, e.g a vector:

struct A
{
int x;
int y;
std::vector<int> z;
};

The sequence

A a;
memset(&a,0,sizeof(A));

would be fatal now, because I overwrite the instanciated vector a.z.

<snip>

You may create a non-virtual base class with only POD data and inherit
from it. In such a way, you could still a memset, but only with thiis
base class.

struct A_
{
int x;
int y;
};

struct A:public A_
{
A() {memset(static_cast<A_ *>(this),0,sizeof(A_);}
std::vector<int> z;
};

Regards,

Zara
Jan 19 '06 #4

Patrick Kowalzick wrote:
Dear all,

I have an existing piece of code with a struct with some PODs.

struct A
{
int x;
int y;
};

This struct is created somewhere and initialized via a memset.


[]

Overload memset() in the same header where A is declared:

void memset(A*, int, size_t);

Note that this overload won't be called if memset is invoked as:

memset(void*)&a, ...);

A more proper way would be to redesign the code, so that it don't do
memset on A's anymore.

Jan 19 '06 #5

Alf P. Steinbach wrote:
* Patrick Kowalzick:
Dear all,

I have an existing piece of code with a struct with some PODs.

struct A
{
int x;
int y;
};

This struct is created somewhere and initialized via a memset.

A a;
memset(&a,0,sizeof(A));

Now I want to extend the structure with an object, e.g a vector:

struct A
{
int x;
int y;
std::vector<int> z;
};


I have a follow on question to this. Given:

unsigned int const max_id = 5;
unsigned int const max_participants = 5;
struct some_struct
{ int some_param;
some_struct()
: some_param( -1) {}
};

struct some_other_struct
{ int some_var;
int some_size;
unsigned char* ptr;
some_other_struct()
: some_var(-1)
, some_size(-1)
, ptr(0)
{}
};

struct someImportantData {
unsigned int c_style_arr[ max_participants ];
some_struct c_style_arr2[ max_id ] [ max_participants ];
some_other_struct c_style_arr3[ max_participants ];
};
int main()
{
someImportantData sid;
for ( int idx(0); idx < max_participants; ++idx )
{
sid.c_style_arr[ idx ] = idx ;
}
typedef std::vector<unsigned int> UINT_VEC;
UINT_VEC myVec(&sid.c_style_arr[0],
&sid.c_style_arr[max_participants] );

UINT_VEC::iterator end = myVec.end();
for ( UINT_VEC::const_iterator it = myVec.begin(); it != end; ++it )
{
std::cout << *it << std::endl;
}

}

Now going from c_style_arr to a vector is easy (as shown below) .
How would I do the c_style_arr2 and c_style_arr3? Part of the issue
with c_sytle_arr2 is based on the fact that I'm still experimenting
with 2-d vectors.

In any event, thanks in advance.

Jan 19 '06 #6
Hello Maxim,
I have an existing piece of code with a struct with some PODs.

struct A
{
int x;
int y;
};

This struct is created somewhere and initialized via a memset.


[]

Overload memset() in the same header where A is declared:

void memset(A*, int, size_t);

Note that this overload won't be called if memset is invoked as:

memset(void*)&a, ...);

A more proper way would be to redesign the code, so that it don't do
memset on A's anymore.


The memset are not too often, so I kicked them :). But it seems to be a good
idea to overload memset, perhaps I missed one.....

void memset(A*, int, size_t)
{
assert( "Please, please do not use memset for this struct");
}

Hmm, or static_assert? Would something like this work as static assert?

// forward for allowed memsets
template < typename T > class memset_functor
{
public:
void * operator()( T* dest, int c, size_t count )
{
return memset(dest,c,count);
}
};

// forward for disallowed memsets
template <> class memset_functor< A >
{
public:
void * operator()( A *, int, size_t )
{
// STATIC_ASSERTION
}
};

template < typename T >
void * memset( T* dest, int c, size_t count )
{
return memset_functor<T>()(dest,c,count);
}

Looks funny. I will test this towmorrow :)

Regards,
Patrick
Jan 19 '06 #7

"Patrick Kowalzick" <pa***************@mapandguide.de> skrev i
meddelandet news:ne********************@proxy.mapandguide.de.. .
Hello Alf,
struct A
{
int x;
int y;
std::vector<int> z;
};
When you have public non-POD members you need to redesign.


Normally I'd never use struct for more complex things :).
In reality the struct is very huge with a bunch of PODs inside, so
using a
ctor would be possible, but quite a lot of work. (I am also scared
to miss
something). How would you proceed to avoid the devastating memset?


When you a "very huge" struct you need to redesign.


Hmm, might be. Lets say very huge in this context is nothing elses
than: I do not want to initialize all the members.
For now, rename the orginal struct to PodA,

struct PodA { ... };

then derive struct A from that,

struct A: PodA
{
A(): PodA() {}
std::vector<int> z;
};


Perfect. Thats a rather good solution. Anyway for this case I will
change to

struct PodA
{
PodA() { memset(this,0,sizeof(PodA)); }
...
};

But now you have a constructor, so it's not a POD anymore. :-(

This is not nice (ok it is ugly), but closer to the original code.


It is ugly!
Bo Persson

Jan 19 '06 #8
> Hmm, or static_assert? Would something like this work as static assert?

// forward for allowed memsets
template < typename T > class memset_functor
{
public:
void * operator()( T* dest, int c, size_t count )
{
return memset(dest,c,count);
}
};

// forward for disallowed memsets
template <> class memset_functor< A >
{
public:
void * operator()( A *, int, size_t )
{
// STATIC_ASSERTION
}
};

template < typename T >
void * memset( T* dest, int c, size_t count )
{
return memset_functor<T>()(dest,c,count);
}

Looks funny. I will test this towmorrow :)


Ok. I tried it, and it does not work.

The specialization memset_functor< A > will be instanciated, even if there
is no call "memset(A,int,size_t)". Like this the static assertion always
fails.

I use now an easier approach, which works on my compiler, but I am not sure
if it is bullet proof:

template < typename T >
void * memset( TTransferDistlibData2 * dest, T c, size_t count )
{
BOOST_STATIC_ASSERT(FALSE);
return NULL;
}

Calling memset(A,..) fails like this to compile.

Kind regards,
Patrick
Jan 20 '06 #9
Hello Bo,
Perfect. Thats a rather good solution. Anyway for this case I will change
to

struct PodA
{
PodA() { memset(this,0,sizeof(PodA)); }
...
};

But now you have a constructor, so it's not a POD anymore. :-(


Hmm, ok. I call it "public class with only PODs inside" :).
This is not nice (ok it is ugly), but closer to the original code.


It is ugly!


no choice.

Regards,
Patrick
Jan 20 '06 #10

"Patrick Kowalzick" <pa***************@mapandguide.de> skrev i
meddelandet news:ne********************@proxy.mapandguide.de.. .
Hello Bo,
Perfect. Thats a rather good solution. Anyway for this case I will
change to

struct PodA
{
PodA() { memset(this,0,sizeof(PodA)); }
...
};

But now you have a constructor, so it's not a POD anymore. :-(


Hmm, ok. I call it "public class with only PODs inside" :).


Ok, I didn't explain it properly:

If it's not a POD, you cannot use memset() on it.
That was the original problem! :-)
Bo Persson
Jan 21 '06 #11
Hello Bo,
Hmm, ok. I call it "public class with only PODs inside" :).
Ok, I didn't explain it properly:

If it's not a POD, you cannot use memset() on it.


Why not? I will take a look in the standard, now, but I was quite sure, that
adding a function to POD-struct will not change the memory structure of this
struct. I see no obvious reason, why this should be dangerous.

If it is dangerous there is still the soution Zara suggests...
That was the original problem! :-)


Not really. The problem was an inner class, which itself may initialize,
inside a structure which is overwirtten by a memset on the outer struct. The
initialization of the inner class is lost (and even worse the instance might
be invalid).

Kind regards,
Patrick
Jan 23 '06 #12
>>> Hmm, ok. I call it "public class with only PODs inside" :).

Ok, I didn't explain it properly:

If it's not a POD, you cannot use memset() on it.


Why not? I will take a look in the standard, now, but I was quite sure,
that adding a function to POD-struct will not change the memory structure
of this struct. I see no obvious reason, why this should be dangerous.


I think, a class with a ctor can still be a POD-class. There fore two cites
from the standard:

"(3.9.10) Arithmetic types (3.9.1), enumeration types, pointer types, and
pointer to member types (3.9.2), and cv-qualified versions of these types
(3.9.3) are collectively called scalar types. Scalar types, POD-struct
types, POD-union types (clause 9), arrays of such types and cv-qualified
versions of these types (3.9.3) are collectively called POD types."

"(9.0.4) {...} A POD-struct is an aggregate class that has no non-static
data members of type non-POD-struct, non-POD-union (or array of such types)
or reference, and has no user-defined copy assignment operator and no
user-defined destructor. Similary, a POD-union is an aggregate union that
has no non-static data members of type non-POD-struct, non-POD-union (or
array of such types) or reference, and has no user-defined copy assignment
operator and no user-defined destructor. A POD class is a class that is
either a POD-struct or a POD-union."

I have no other non-POD typed, nor a copy assignment, nor a dtor. So it is
still a POD? But what about a vtable? Might this still be a POD?

Regards,
Patrick
Jan 23 '06 #13
> I think, a class with a ctor can still be a POD-class. There fore two
cites from the standard:
Bullshit :).
"(3.9.10) Arithmetic types (3.9.1), enumeration types, pointer types, and
pointer to member types (3.9.2), and cv-qualified versions of these types
(3.9.3) are collectively called scalar types. Scalar types, POD-struct
types, POD-union types (clause 9), arrays of such types and cv-qualified
versions of these types (3.9.3) are collectively called POD types."

"(9.0.4) {...} A POD-struct is an aggregate class that has no non-static
data members of type non-POD-struct, non-POD-union (or array of such
types) or reference, and has no user-defined copy assignment operator and
no user-defined destructor. Similary, a POD-union is an aggregate union
that has no non-static data members of type non-POD-struct, non-POD-union
(or array of such types) or reference, and has no user-defined copy
assignment operator and no user-defined destructor. A POD class is a class
that is either a POD-struct or a POD-union."

I have no other non-POD typed, nor a copy assignment, nor a dtor. So it is
still a POD? But what about a vtable? Might this still be a POD?


"[8.5.1.1] An aggregate is an array or a class (clause 9) with no
user-declared constructors (12.1), no private or protected non-static data
members (clause 11), no base classes (clause 10), and no virtual functions
(10.3)."

And for sure, read the FAQ:
http://www.parashift.com/c++-faq-lit....html#faq-26.7

Thanks all a lot for you input in this thread. I hope I got it now.

Kind regards,
Patrick
Jan 23 '06 #14
Hello Alf,
For now, rename the orginal struct to PodA,

struct PodA { ... };

then derive struct A from that,

struct A: PodA
{
A(): PodA() {}
std::vector<int> z;
};

and also check that your compiler supports default-initialization of
POD's (unfortunately some don't).


I checked this. Some of my compilers support default-initialization, some
not :(. This is really sad.

So I use now this here (even if there is a difference to memset in the
result):

struct A_PODs{ ... };

struct A : public A_PODs
{
A()
{
static A_PODs zero_init = { 0 };
// static A_PODs zero_init = { }; // would be enough, but does not
work on all compilers.
*(static_cast< A_PODs * >(this)) = zero_init; // is this safe?
}
};
Kind regards,
Patrick
Jan 24 '06 #15

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

Similar topics

5
by: Joe C | last post by:
I'm a hobbiest, and made the forray into c++ from non-c type languages about a year ago. I was "cleaning up" some code I wrote to make it more "c++ like" and have a few questions. I'm comfortable...
17
by: Nollie | last post by:
Say you have a struct: struct MYSTRUCT { int x; int y; int w; int h; };
6
by: bob_jenkins | last post by:
{ const void *p; (void)memset((void *)p, ' ', (size_t)10); } Should this call to memset() be legal? Memset is of type void *memset(void *, unsigned char, size_t) Also, (void *) is the...
27
by: volunteers | last post by:
I met a question about memset and have no idea right now. Could anybody give a clue? Thanks memset is sometimes used to initialize data in a constructor like the example below. What is the...
18
by: dykeinthebox | last post by:
Consider the following program: #include <stdlib.h> #include <string.h> int main( void ) { void *p = malloc( 4 ); if ( p ) {
43
by: JohnQ | last post by:
Are a default constructor, destructor, copy constructor and assignment operator generated by the compiler for a struct if they are not explicitely defined? I think the answer is yes, because...
13
by: JohnQ | last post by:
The implementation of classes with virtual functions is conceptually easy to understand: they use vtables. Which begs the question about POD structs: how are they associated with their member...
12
by: Martin Wells | last post by:
I'm trying to come up with a fully-portable macro for supplying memset with an unsigned char rather than an int. I'm going to think out loud as I go along. . . I'll take a sample system before I...
18
by: Gaijinco | last post by:
I'm having a headache using memset() Given: int v; memset((void*)v, 1, sizeof(v)); Can I be 100% positive than v = 1 for i 0, or there is something else I have to do?.
32
by: viza | last post by:
Hi all Is this assertion guaranteed? { void *vptr; memset( & vptr, 0, sizeof vptr); assert( NULL == vptr ); } What about these ones?
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?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.