Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy does memcpy fail copying to a local array member of a simple object?
    primarykey
    data
    text
    <p>Classic memcpy gotcha with C arrays as function arguments. As pointed out below, I have an error in my code but the erroneous code worked in a local context!</p> <p>I just encountered this weird behaviour in a porting job, where I'm emulating the Macintosh Picture opcode playback using objects. My DrawString object was drawing garbage on playback because it apparently failed to copy the string argument. The following is a test case I wrote - note how a manual copying loop works but memcpy fails. Tracing in the Visual Studio debugger shows the memcpy ovewrites the destination with garbage.</p> <p>Memcpy on two local Str255 arrays works fine.</p> <p>When one of them is a member in an object on the stack, it fails (in other testing it also fails when the object is on the heap).</p> <p>The following sample code shows the memcpy being invoked in an operator=. I moved it there after it failed in a constructor but there was no difference.</p> <pre><code>typedef unsigned char Str255[257]; // snippet that works fine with two local vars Str255 Blah("\004Blah"); Str255 dest; memcpy(&amp;dest, &amp;Blah, sizeof(Str255)); // THIS WORKS - WHY HERE AND NOT IN THE OBJECT? /*! class to help test CanCopyStr255AsMember */ class HasMemberStr255 { public: HasMemberStr255() { mStr255[0] = 0; } HasMemberStr255(const Str255 s) { for (int i = 0; i&lt;257; ++i) { mStr255[i] = s[i]; if (s[i]==0) return; } } /// fails void operator=(const Str255 s) { memcpy(&amp;mStr255, &amp;s, sizeof(Str255)); }; operator const Str255&amp;() { return mStr255; } private: Str255 mStr255; }; - /*! Test trivial copying technique to duplicate a string Added this variant using an object because of an apparent Visual C++ bug. */ void TestMacTypes::CanCopyStr255AsMember() { Str255 initBlah("\004Blah"); HasMemberStr255 blahObj(initBlah); // using the operator= which does a memcpy fails blahObj = initBlah; const Str255&amp; dest = blahObj; // invoke cast operator to get private back out CPPUNIT_ASSERT( dest[0]=='\004' ); CPPUNIT_ASSERT( dest[1]=='B' ); CPPUNIT_ASSERT( dest[2]=='l' ); CPPUNIT_ASSERT( dest[3]=='a' ); CPPUNIT_ASSERT( dest[4]=='h' ); CPPUNIT_ASSERT( dest[5]=='\0' ); // trailing null } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload