BUG: Access violation occurs when copied objects contain pointers to their own members while using the CArray class in Visual Studio .NET or in Visual Studio 2005 (822369)



The information in this article applies to:

  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET (2003)
  • Microsoft Visual C++ .NET (2002)
  • Microsoft Visual C++, 32-bit Professional Edition 6.0
  • Microsoft Visual C++, 32-bit Enterprise Edition 6.0

SYMPTOMS

The CArray class may not handle C++ classes correctly. When you copy objects in memory without using constructors and destructors of the objects, and you access a member that is a pointer to another member in an object, you may receive an access violation, or an invalid value may be returned.

CAUSE

The CArray Microsoft Foundation Classes (MFC) class uses the memcpy function to copy the objects in memory. This behavior causes invalid references. When the copied objects contain pointers to their own members ("this" pointer), the memcpy function may cause invalid references.

WORKAROUND

To work around this problem, do not use members in an object that are pointers to other members in the object or to the object itself ("this" pointer) with an element that is copied.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

The CArray class supports arrays that are similar to C arrays, but that can dynamically become smaller or larger as necessary. CArray::SetSize uses the memcpy function. You must use CArray::SetSize to establish the size and to allocate memory before you use this array. Otherwise, adding elements to your array may cause frequent reallocation and copying. Frequent reallocation and copying are inefficient and can fragment memory.

The following sample code may reproduce this behavior:
//Header File (TestCopy.h)
#pragma once
#include "resource.h"

class MyClass
{
public:

   MyClass() {
										mySelf = this;
   }

   MyClass( MyClass *mySelf ) {
										mySelf = this;
   }
	
   MyClass *mySelf;
};
//Implementation File (TestCopy.cpp)
#include "stdafx.h"
#include "TestCopy.h"
#include <afxtempl.h>

void main()
{
	
	MyClass *myObj = new MyClass();

	if (myObj == myObj->mySelf)
	printf("Addresses are matching\n");
	else
	printf("Addresses are NOT matching\n");

	CArray<MyClass, MyClass> m_myArray;

	m_myArray.Add(myObj);
	m_myArray.SetSize(32,128);

	MyClass *myObj1 = (MyClass *) m_myArray.GetData();

	if (myObj1 == myObj1->mySelf)
	printf("Addresses are matching even after CArray Operation \n");
	else
	printf("Addresses are NOT matching after CArray Operation \n");
}
//Output is as follows
Addresses are matching
Addresses are NOT matching after CArray Operation

Modification Type:MinorLast Reviewed:1/18/2006
Keywords:kbCollectionClass kbProgramming kbbug KB822369 kbAudDeveloper