Click here to Skip to main content
15,917,731 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, I've seen some code where data structure was initialized with memcpy.
Was curious if it is a good idea?
e.g.
C++
auto_ptr<MyDataStructure> tmp(new MyDataStructure());
memset(tmp.get(),0x0,sizeof(MyDataStructure));
Posted
Updated 20-May-13 12:05pm
v3

I cosider this a broken way of initialization in C++.
It breaks the OOP encapsulation and information hiding - you override with brute foce whatever the constructor did/was supposed to do.

Why does the client of a class know better than the class itself how an instance is initialized.
This approach may produce leaks (a constructed memory address gets overridden by 0), initialize enum members to 0 (while that enum may not have a 0-value), etc.

This initialization idiom is most likely a legacy approach of some C-veteran. C does not know constructors, so it was the only way and safe those days to initialize the allocated memory after a alloc/calloc/malloc.

The new operator calls also malloc of the appropriate size and then calls the constructor of that class by providing that memory as the this pointer to the constructor.

My advise:
- in C++: never ever do this - you have constructors for this.
- in C: definitively do it (or use calloc).

Cheers
Andi
 
Share this answer
 
Comments
CPallini 20-May-13 18:04pm    
Good points, my 5.
Andreas Gieriet 20-May-13 18:08pm    
Thanks for your 5!
Cheers
Andi
Dan page 21-May-13 2:15am    
Hi Andreas. Thanks. But please note MyDataStructure - is a "struct" it is not a Class. What to do in this case then?
Andreas Gieriet 21-May-13 4:30am    
A struct is identical to a class in C++. The only difference is the default access specifier: In a class, all is private by default, in a struct, all is public by default. See also What are the differences between struct and class in C++.
if your structor has virtal functions, disaster comes. e.g code as follow, run it and see what will happen.
C++
typedef struct tagTestStructor
{
	virtual void testOut(){ std::cout << "this is a virtual function" << std::endl;}
	int m_nVal;
	char m_cVal;
	// ...
}TestStructor;

int _tmain(int argc, _TCHAR* argv[])
{
	TestStructor objTest;
	memset(&objTest, 0, sizeof(objTest) );

	// use a pointer to test
	TestStructor* pObjTest = &objTest;
	pObjTest->testOut();
}
 
Share this answer
 
Comments
«_Superman_» 20-May-13 23:38pm    
Your point in absolutely valid. 10 points for this.
However, it may not be applicable to this case because the destination in memset is tmp.get() and not &tmp.
Although I don't know how auto_ptr is implemented, the get method could return an address after the virtual pointer so that the vptr is not initialized to 0.

Also, I agree with others that this sort of initialization is not the right way to do it.
Another thing I would like to add here is that auto_ptr has been deprecated and should not be used. unique_ptr must be used instead.
BCN-163 22-May-13 22:37pm    
you could use follow code to test get method of auto_ptr.
typedef struct tagTestStructor
{
virtual void testOut(){ std::cout << "this is a virtual function" << std::endl;}
int m_nVal;
char m_cVal;
// ...
}TestStructor;

int _tmain(int argc, _TCHAR* argv[])
{
TestStructor* pTmpNew = new TestStructor();
auto_ptr<teststructor> apTmp(pTmpNew);

assert(apTmp.get() == pTmpNew);

memset(apTmp.get(),0x0,sizeof(TestStructor));

apTmp->testOut();
}
Andreas Gieriet 21-May-13 11:06am    
My 5! It may/may not fail, depending on the C++ compiler. Things get worse with multi inheritance (diamond pattern) and casting...
Cheers
Andi
BCN-163 22-May-13 22:41pm    
as I know, it will always fail. I have heard a lot about the different implement of C++ compiler. but I never met one. would you give me some tips? really appreciate.
Andreas Gieriet 23-May-13 4:17am    
See Inside the C++ Object Model for some insight on how it might be implemented.
Cheers
Andi
I agree with the others that this is not the right way to initialize it.

Another thing I would like to add is that auto_ptr should not be used at all because it has been deprecated.
Use unique_ptr instead.

See here - http://www.cplusplus.com/reference/memory/auto_ptr/[^]
 
Share this answer
 
Comments
Andreas Gieriet 21-May-13 11:05am    
My 5!
Cheers
Andi
Always a good idea (essential) to initialize your data by whatever means. Otherwise one day, somewhere, your uninitialized structure may be read and will contain something random that looks like it might be real data but it isn't.
 
Share this answer
 
Comments
Andreas Gieriet 20-May-13 17:51pm    
While proper initialization is crucial to all robust software, I consider this particular approach in C++ as broken.
See my reasoning in my solution #2.
Cheers
Andi

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900