zero memory

  • Thread starter Christopher Pisz
  • Start date
C

Christopher Pisz

What is the C++ way to zero out memory after calling operator new on a
struct?

A constructor is not possible in this case nor is a class, because the
people using my code c-stlye cast a pointer to the first member of the
struct to a pointer to the entrire struct later on in the code.
 
V

Victor Bazarov

Christopher said:
What is the C++ way to zero out memory after calling operator new on a
struct?

To zero out what memory? What does "calling operator new on a struct"
mean? Could you post code instead of English?
A constructor is not possible in this case nor is a class, because the
people using my code c-stlye cast a pointer to the first member of the
struct to a pointer to the entrire struct later on in the code.

Huh?

V
 
D

Default User

Christopher said:
What is the C++ way to zero out memory after calling operator new on
a struct?

Why do you want to? What problem does this solve?
A constructor is not possible in this case nor is a class, because
the people using my code c-stlye cast a pointer to the first member
of the struct to a pointer to the entrire struct later on in the code.

If it's a POD, you can use memcpy to set the whole thing to
all-bits-zero. That's not always what you want, and frankly is usually
a poor design.





Brian
 
G

Gianni Mariani

Victor said:
To zero out what memory? What does "calling operator new on a struct"
mean? Could you post code instead of English?




Huh?

I'm guessing but Mr Pisz could probably benefit from knowing what this does:

struct A
{
int X;
int Y;
char Z[30];
// other POD members ...
};

A x = A();
 
C

Christopher Pisz

Victor Bazarov said:
To zero out what memory? What does "calling operator new on a struct"
mean? Could you post code instead of English?


Huh?

V


typedef struct _MYSTRUCT
{
OVERLAPPED overlapped;
int mamajama;
_MYSTRUCT * next;
} *PMYSTRUCT, MYSTRUCT;

Foo()
{
PMYSTRUCT = new MYSTRUCT;

// now set all members of the struct to 0
}


// later, they do this:
SomeFunction(OVERLAPPED * overlapped)
{
PMYSTRUCT happystruct = (PMYSTRUCT) overlapped;
int x = happystruct->mamajama;

//etc etc.
}
 
I

Ian Collins

Christopher said:
typedef struct _MYSTRUCT
{
OVERLAPPED overlapped;
int mamajama;
_MYSTRUCT * next;
} *PMYSTRUCT, MYSTRUCT;

Foo()
{
PMYSTRUCT = new MYSTRUCT;

// now set all members of the struct to 0
}


// later, they do this:
SomeFunction(OVERLAPPED * overlapped)
{
PMYSTRUCT happystruct = (PMYSTRUCT) overlapped;
int x = happystruct->mamajama;

//etc etc.
}
It looks like someone is very confused between C and C++ idioms.
 
R

red floyd

Christopher said:
typedef struct _MYSTRUCT

Ill formed program. Any identifier with a leading underscore, followed
by an uppercase letter is reserved to the implementation.
{
OVERLAPPED overlapped;
int mamajama;
_MYSTRUCT * next;
} *PMYSTRUCT, MYSTRUCT;

Foo()
{
PMYSTRUCT = new MYSTRUCT;

// now set all members of the struct to 0
}


// later, they do this:
SomeFunction(OVERLAPPED * overlapped)
{
PMYSTRUCT happystruct = (PMYSTRUCT) overlapped;
int x = happystruct->mamajama;

//etc etc.
}

Also, as someone else pointed out, this is essentially C, except for the
use of new.
 
J

Jack Klein

Why do you want to? What problem does this solve?


If it's a POD, you can use memcpy to set the whole thing to
^^^^^^

I know you know that should be memset(). Silly typo.
all-bits-zero. That's not always what you want, and frankly is usually
a poor design.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
A

ajk

What is the C++ way to zero out memory after calling operator new on a
struct?

A constructor is not possible in this case nor is a class, because the
people using my code c-stlye cast a pointer to the first member of the
struct to a pointer to the entrire struct later on in the code.

so memset() should do the trick

"the c++ way" would be to have a class and to initialize it in the
ctor

e.g.

class CMYSTRUCT : public MYSTRUCT
{
public:
CMYSTRUCT() {
memset(&overlapped,0,sizeof(overlapped)); mamajama=0; next=NULL; }
};

Foo()
{
PMYSTRUCT = new CMYSTRUCT;
}

or make the MYSTRUCT a class
 
G

Gianni Mariani

ajk said:
so memset() should do the trick

"the c++ way" would be to have a class and to initialize it in the
ctor

e.g.

class CMYSTRUCT : public MYSTRUCT
{
public:
CMYSTRUCT() {
memset(&overlapped,0,sizeof(overlapped)); mamajama=0; next=NULL; }

You really want to avoid using memset. It will bite you one day.

Try this:

CMYSTRUCT() : MYSTRUCT( MYSTRUCT() ) {}

But your problem does not end there :-(
};

Foo()
{
PMYSTRUCT = new CMYSTRUCT;

In this case, you're calling new on CMYSTRUCT and I expect that you'll
call delete on a MYSTRUCT. That's undefined. Bad things will happen if
don't modify that habbit.
}

or make the MYSTRUCT a class

MYSTRUCT is a class.



I just thought of yet another way - this one will create a default
constructed or zero initialized POD object depending on what type of
pointer you're trying to assign it to.

struct InitObj
{
template <typename T>
operator T * ()
{
return new T();
}
};

// usage - template automagically figures out which type to new
PMYSTRUCT * mys = InitObj();

int * z = InitObj();


Note the lack of a memset call and note that the code will work for POD
types as well as non POD types.
 
J

Jacek Dziedzic

ajk said:
so memset() should do the trick

"the c++ way" would be to have a class and to initialize it in the
ctor

e.g.

class CMYSTRUCT : public MYSTRUCT
{
public:
CMYSTRUCT() {
memset(&overlapped,0,sizeof(overlapped)); mamajama=0; next=NULL; }
};

Foo()
{
PMYSTRUCT = new CMYSTRUCT;
}

or make the MYSTRUCT a class

Wait a second. Doesn't adding a c'tor make it non-POD and
hence unsuitable for a memset()?

- J.
 
D

Dave Rahardja

What is the C++ way to zero out memory after calling operator new on a
struct?

A constructor is not possible in this case nor is a class, because the
people using my code c-stlye cast a pointer to the first member of the
struct to a pointer to the entrire struct later on in the code.

Since you're essentially doomed to maintaining this code in C anyway, just
forget about C++ and treat this as a C struct.

-dr
 
C

Christopher Pisz

Ian Collins said:
It looks like someone is very confused between C and C++ idioms.



It isn't me. I know darn well how I would do it if I didn't have 3rd party
limitations. The problem is that the c style cast, that they force me to
use, in turn forces the structure.
 
D

Default User

Jack said:
On 5 Apr 2007 22:06:14 GMT, "Default User" <[email protected]>
wrote in comp.lang.c++:
^^^^^^

I know you know that should be memset(). Silly typo.

Man! Yes, of course.

I guess my only defense is that I rarely use memset(), even in C.




Brian
 
G

Gianni Mariani

Jacek said:
ajk wrote: ....

Wait a second. Doesn't adding a c'tor make it non-POD and
hence unsuitable for a memset()?

Yes, but that's not what is happening. memset is being called on a
member which is a POD.
 
A

ajk

In this case, you're calling new on CMYSTRUCT and I expect that you'll
call delete on a MYSTRUCT. That's undefined. Bad things will happen if
don't modify that habbit.

why do you expect that? ok i have not added any virtual dtor as was
not providing a full class. just showing the principle.
MYSTRUCT is a class.

technically you are right, although what I meant was to make it a
"real" class with ctor/dtor etc.
I just thought of yet another way - this one will create a default
constructed or zero initialized POD object depending on what type of
pointer you're trying to assign it to.

struct InitObj
{
template <typename T>
operator T * ()
{
return new T();
}
};

// usage - template automagically figures out which type to new
PMYSTRUCT * mys = InitObj();

int * z = InitObj();


Note the lack of a memset call and note that the code will work for POD
types as well as non POD types.

ok that's in a way elegant, but a bit difficult for maintenance
programmers to troubleshoot
 
G

Gianni Mariani

ajk said:
On Fri, 06 Apr 2007 05:39:34 -0700, Gianni Mariani



ok that's in a way elegant, but a bit difficult for maintenance
programmers to troubleshoot

That's one serious cop-out. Arguing to have mediocre engineers is an
unsupportable argument.


Let's see which one is more maintainable ....
..................
code in common header file....

struct InitObj
{
template <typename T>
operator T * ()
{
return new T();
}
};
................


................
application code.....
PMYSTRUCT mys = InitObj();
................

vs - in every instance ...

memset(&overlapped,0,sizeof(overlapped)) + other mumbo jumbo with all
kinds of potential for programmer errors.



I know what I would like my engineers to maintain.
 
G

Gianni Mariani

Christopher said:
What is the C++ way to zero out memory after calling operator new on a
struct?

A constructor is not possible in this case nor is a class, because the
people using my code c-stlye cast a pointer to the first member of the
struct to a pointer to the entrire struct later on in the code.

Note that there are a number of win32 structs that must be initialized
not only with zeros but with a member set to the size of the struct.
e.g. IMAGEHLP_SYMBOL64

The code below (checked on gcc) should automatically initialize an
entire struct to zeros and insert the right value in the "sizeofstruct"
member if it exists.

I did have a problem with visual studio on this technique a while back,
let's hope things have improved.


// This is used to initialize Win32 structs that contain a
// "sizeofstruct" structure.

struct NoMemb { char a[1]; };
struct Memb_SizeOfStruct { char a[2]; };
struct Memb_sizeofstruct { char a[3]; };

template <int w_val>
struct InitSizeOf;

template <>
struct InitSizeOf< sizeof( NoMemb ) >
{
template <typename U>
inline static void ObjInitSel( U & obj )
{
}
};

template <>
struct InitSizeOf< sizeof( Memb_SizeOfStruct ) >
{
template <typename U>
inline static void ObjInitSel( U & obj )
{
obj.SizeOfStruct = sizeof( obj );
}
};

template <>
struct InitSizeOf< sizeof( Memb_sizeofstruct ) >
{
template <typename U>
inline static void ObjInitSel( U & obj )
{
obj.sizeofstruct = sizeof( obj );
}
};

template <typename T>
struct InitObject
{
private:

struct xA {};
struct xB : xA {};

template <int w_size>
struct Detect
{
};

public:

template <typename U>
inline static Memb_sizeofstruct ObjInitSel(
U & obj, xB * b, Detect< sizeof(&U::sizeofstruct) > * = 0
);

template <typename U>
inline static Memb_SizeOfStruct ObjInitSel(
U & obj, xB * b, Detect< sizeof(&U::SizeOfStruct) > * = 0
);

template <typename U>
inline static NoMemb ObjInitSel( U & obj, xA * a );

inline static void ObjInit( T & obj )
{
typedef xB * bp;

InitSizeOf<sizeof( ObjInitSel(obj, bp()))>::ObjInitSel( obj );
}
};

struct InitStruct
{

template <typename T>
inline operator T ()
{
T obj = T();
InitObject<T>().ObjInit( obj );

return obj;
}

template <typename T>
inline operator T * ()
{
T * obj = new T();

InitObject<T>().ObjInit( * obj );

return obj;
}

};


/////////// test code

struct A
{
int a;
char x[10];
};


struct B
{
int SizeOfStruct;
char x[15];
};


struct C
{
int sizeofstruct;
char x[22];
};

B Bfoo()
{
return InitStruct();
}

C Cfoo()
{
return InitStruct();
}

A Afoo()
{
return InitStruct();
}


int main()
{

// make dynamically allocated version
C * c = InitStruct();

delete c;

Bfoo();
Cfoo();
Afoo();
}
 
A

ajk

That's one serious cop-out. Arguing to have mediocre engineers is an
unsupportable argument.

no, its not an unsuportable argument - coding so that its clear is
what its about.
Let's see which one is more maintainable ....
.................
code in common header file....

struct InitObj
{
template <typename T>
operator T * ()
{
return new T();
}
};
...............


...............
application code.....
PMYSTRUCT mys = InitObj();
...............

vs - in every instance ...

memset(&overlapped,0,sizeof(overlapped)) + other mumbo jumbo with all
kinds of potential for programmer errors.

mumbo jumbo? lol whatever
I know what I would like my engineers to maintain.

your solution has two drawbacks as it allocates memory on heap:
it requires whoever uses it to know that memory is allocated second
second allocating memory on heap just because you want to initialize
it isn't effective.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top