CArray Class
The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.
The latest version of this topic can be found at CArray Class.
Supports arrays that are like C arrays, but can dynamically reduce and grow as necessary.
Syntax
template <class TYPE, class ARG_TYPE = const TYPE&>
class CArray : public CObject
Parameters
TYPE
Template parameter that specifies the type of objects stored in the array. TYPE
is a parameter that is returned by CArray
.
ARG
_ TYPE
Template parameter that specifies the argument type that is used to access objects stored in the array. Often a reference to TYPE
. ARG_TYPE
is a parameter that is passed to CArray
.
Members
Public Constructors
Name | Description |
---|---|
CArray::CArray | Constructs an empty array. |
Public Methods
Name | Description |
---|---|
CArray::Add | Adds an element to the end of the array; grows the array if necessary. |
CArray::Append | Appends another array to the array; grows the array if necessary |
CArray::Copy | Copies another array to the array; grows the array if necessary. |
CArray::ElementAt | Returns a temporary reference to the element pointer within the array. |
CArray::FreeExtra | Frees all unused memory above the current upper bound. |
CArray::GetAt | Returns the value at a given index. |
CArray::GetCount | Gets the number of elements in this array. |
CArray::GetData | Allows access to elements in the array. Can be NULL. |
CArray::GetSize | Gets the number of elements in this array. |
CArray::GetUpperBound | Returns the largest valid index. |
CArray::InsertAt | Inserts an element (or all the elements in another array) at a specified index. |
CArray::IsEmpty | Determines whether the array is empty. |
CArray::RemoveAll | Removes all the elements from this array. |
CArray::RemoveAt | Removes an element at a specific index. |
CArray::SetAt | Sets the value for a given index; array not allowed to grow. |
CArray::SetAtGrow | Sets the value for a given index; grows the array if necessary. |
CArray::SetSize | Sets the number of elements to be contained in this array. |
Public Operators
Name | Description |
---|---|
operator[] | Sets or gets the element at the specified index. |
Remarks
Array indexes always start at position 0. You can decide whether to fix the upper bound or enable the array to expand when you add elements past the current bound. Memory is allocated contiguously to the upper bound, even if some elements are null.
Note
Most methods that resize a CArray
object or add elements to it use memcpy_s to move elements. This is a problem because memcpy_s
is not compatible with any objects that require the constructor to be called. If the items in the CArray
are not compatible with memcpy_s
, you must create a new CArray
of the appropriate size. You must then use CArray::Copy and CArray::SetAt to populate the new array because those methods use an assignment operator instead of memcpy_s
.
As with a C array, the access time for a CArray
indexed element is constant and is independent of the array size.
Tip
Before using an array, use SetSize to establish its size and allocate memory for it. If you do not use SetSize
, adding elements to your array causes it to be frequently reallocated and copied. Frequent reallocation and copying are inefficient and can fragment memory.
If you need a dump of individual elements in an array, you must set the depth of the CDumpContext object to 1 or larger.
Certain member functions of this class call global helper functions that must be customized for most uses of the CArray
class. See the topic Collection Class Helpers in the MFC Macros and Globals section.
Array class derivation is like list derivation.
For more information about how to use CArray
, see the article Collections.
Inheritance Hierarchy
CArray
Requirements
Header:
afxtempl.h
CArray::Add
Adds a new element to the end of an array, growing the array by 1.
INT_PTR Add(ARG_TYPE newElement);
Parameters
ARG_TYPE
Template parameter specifying the type of arguments referencing elements in this array.
newElement
The element to be added to this array.
Return Value
The index of the added element.
Remarks
If SetSize has been used with an nGrowBy
value greater than 1, then extra memory may be allocated. However, the upper bound will increase by only 1.
Example
// example for CArray::Add
CArray<CPoint,CPoint> ptArray;
CPoint pt(10,20);
ptArray.Add(pt); // Element 0
ptArray.Add(CPoint(30,40)); // Element 1
CArray::Append
Call this member function to add the contents of one array to the end of another.
INT_PTR Append(const CArray& src);
Parameters
src
Source of the elements to be appended to an array.
Return Value
The index of the first appended element.
Remarks
The arrays must be of the same type.
If necessary, Append may allocate extra memory to accommodate the elements appended to the array.
Example
CArray<CPoint,CPoint> myArray1, myArray2;
// Add elements to the second array.
myArray2.Add(CPoint(11, 22));
myArray2.Add(CPoint(12, 42));
// Add elements to the first array and also append the second array.
myArray1.Add(CPoint(1, 2));
myArray1.Append(myArray2);
CArray::CArray
Constructs an empty array.
CArray();
Remarks
The array grows one element at a time.
Example
CArray<CPoint,CPoint> ptArray;
CArray::Copy
Use this member function to copy the elements of one array to another.
void Copy(const CArray& src);
Parameters
src
Source of the elements to be copied to an array.
Remarks
Call this member function to overwrite the elements of one array with the elements of another array.
Copy does not free memory; however, if necessary, Copy may allocate extra memory to accommodate the elements copied to the array.
Example
CArray<CPoint,CPoint> myArray1, myArray2;
// Add elements to the second array.
myArray2.Add(CPoint(11, 22));
myArray2.Add(CPoint(12, 42));
// Copy the elements from the second array to the first.
myArray1.Copy(myArray2);
CArray::ElementAt
Returns a temporary reference to the specified element within the array.
TYPE& ElementAt(INT_PTR nIndex);
const TYPE& ElementAt(INT_PTR nIndex) const;
Parameters
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by GetUpperBound.
Return Value
A reference to an array element.
Remarks
It is used to implement the left-side assignment operator for arrays.
Example
See the example for GetSize.
CArray::FreeExtra
Frees any extra memory that was allocated while the array was grown.
void FreeExtra();
Remarks
This function has no effect on the size or upper bound of the array.
Example
See the example for GetData.
CArray::GetAt
Returns the array element at the specified index.
TYPE& GetAt(INT_PTR nIndex);
const TYPE& GetAt(INT_PTR nIndex) const;
Parameters
TYPE
Template parameter specifying the type of the array elements.
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by GetUpperBound.
Return Value
The array element currently at this index.
Remarks
Passing a negative value or a value greater than the value returned by GetUpperBound
will result in a failed assertion.
Example
CArray<CPoint,CPoint> myArray;
CPoint pt;
// Add elements to the array.
for (int i = 0; i < 10; i++)
myArray.Add(CPoint(i, 2 * i));
// Modify all the points in the array.
for (int i = 0; i <= myArray.GetUpperBound(); i++)
{
pt = myArray.GetAt(i);
pt.x = 0;
myArray.SetAt(i, pt);
}
CArray::GetCount
Returns the number of array elements.
INT_PTR GetCount() const;
Return Value
The number of items in the array.
Remarks
Call this method to retrieve the number of elements in the array. Because indexes are zero-based, the size is 1 greater than the largest index. Calling this method will generate the same result as the CArray::GetSize method.
Example
CArray<CPoint,CPoint> myArray;
// Add elements to the array.
for (int i = 0; i < 10; i++)
myArray.Add(CPoint(i, 2 * i));
// Modify all the points in the array.
for (int i = 0; i < myArray.GetCount(); i++)
{
CPoint& pt = myArray.ElementAt(i);
pt.x = 0;
}
CArray::GetData
Use this member function to gain direct access to the elements in an array.
const TYPE* GetData() const;
TYPE* GetData();
Parameters
TYPE
Template parameter specifying the type of the array elements.
Return Value
A pointer to an array element.
Remarks
If no elements are available, GetData
returns a null value.
While direct access to the elements of an array can help you work more quickly, use caution when calling GetData
; any errors you make directly affect the elements of your array.
Example
CArray<CPoint,CPoint> myArray;
// Allocate memory for at least 32 elements.
myArray.SetSize(32, 128);
// Add elements to the array.
CPoint* pPt = (CPoint*) myArray.GetData();
for (int i = 0; i < 32; i++, pPt++)
*pPt = CPoint(i, 2*i);
// Only keep first 5 elements and free extra (unused) bytes.
myArray.SetSize(5, 128);
myArray.FreeExtra();
#if _DEBUG
afxDump.SetDepth(1);
afxDump << "myArray: " << &myArray << "\n";
#endif
CArray::GetSize
Returns the size of the array.
INT_PTR GetSize() const;
Remarks
Because indexes are zero-based, the size is 1 greater than the largest index. Calling this method will generate the same result as the CArray::GetCount method.
Example
CArray<CPoint,CPoint> myArray;
// Add elements to the array.
for (int i = 0; i < 10; i++)
myArray.Add(CPoint(i, 2*i));
// Modify all the points in the array.
for (int i = 0; i < myArray.GetSize(); i++)
{
CPoint& pt = myArray.ElementAt(i);
pt.x = 0;
}
CArray::GetUpperBound
Returns the current upper bound of this array.
INT_PTR GetUpperBound() const;
Remarks
Because array indexes are zero-based, this function returns a value 1 less than GetSize
.
The condition GetUpperBound( ) = –1 indicates that the array contains no elements.
Example
See the example for CArray::GetAt.
CArray::InsertAt
The first version of InsertAt
inserts one element (or multiple copies of an element) at a specified index in an array.
void InsertAt(
INT_PTR nIndex,
ARG_TYPE newElement,
INT_PTR nCount = 1);
void InsertAt(
INT_PTR nStartIndex,
CArray* pNewArray);
Parameters
nIndex
An integer index that may be greater than the value returned by GetUpperBound
.
ARG_TYPE
Template parameter specifying the type of elements in this array.
newElement
The element to be placed in this array.
nCount
The number of times this element should be inserted (defaults to 1).
nStartIndex
An integer index that may be greater than the value returned by GetUpperBound.
pNewArray
Another array that contains elements to be added to this array.
Remarks
In the process, it shifts up (by incrementing the index) the existing element at this index, and it shifts up all the elements above it.
The second version inserts all the elements from another CArray
collection, starting at the nStartIndex
position.
The SetAt
function, in contrast, replaces one specified array element and does not shift any elements.
Example
// example for CArray::InsertAt
CArray<CPoint,CPoint> ptArray;
ptArray.Add(CPoint(10,20)); // Element 0
ptArray.Add(CPoint(30,40)); // Element 1 (will become element 2)
ptArray.InsertAt(1, CPoint(50,60)); // New element 1
CArray::IsEmpty
Determines whether the array is empty.
BOOL IsEmpty() const;
Return Value
Nonzero if the array contains no elements; otherwise 0.
CArray::operator []
These subscript operators are a convenient substitute for the SetAt and GetAt functions.
TYPE& operator[](INT_PTR nIndex);
const TYPE& operator[](INT_PTR nIndex) const;
Parameters
TYPE
Template parameter specifying the type of elements in this array.
nIndex
Index of the element to be accessed.
Remarks
The first operator, called for arrays that are not const, may be used on either the right (r-value) or the left (l-value) of an assignment statement. The second, called for const arrays, may be used only on the right.
The Debug version of the library asserts if the subscript (either on the left or right side of an assignment statement) is out of bounds.
Example
CArray<CPoint,CPoint> myArray;
// Add elements to the array.
for (int i = 0; i < 10; i++)
myArray.Add(CPoint(i, 2*i));
// Modify all the points in the array.
for (int i = 0; i <= myArray.GetUpperBound(); i++)
{
myArray[i].x = 0;
}
CArray::RelocateElements
Relocates data to a new buffer when the array should grow or shrink.
template<class TYPE, class ARG_TYPE>
AFX_INLINE void CArray<TYPE, ARG_TYPE>::RelocateElements(
TYPE* pNewData,
const TYPE* pData,
INT_PTR nCount);
Parameters
pNewData
A new buffer for the array of elements.
pData
The old array of elements.
nCount
Number of elements in the old array.
Remarks
pNewData
is always large enough to hold all the pData
elements.
The CArray implementation uses this method to copy the old data to a new buffer when the array should grow or shrink (when SetSize or FreeExtra are called). The default implementation just copies the data.
For arrays in which an element contains a pointer to one of its own members, or another structure contains a pointer to one of the array elements, the pointers are not updated in plain copy. In this case, you can correct pointers by implementing a specialization of RelocateElements
with the relevant types. You are also responsible for data copying.
CArray::RemoveAll
Removes all the elements from this array.
void RemoveAll();
Remarks
If the array is already empty, the function still works.
Example
CArray<CPoint,CPoint> myArray;
// Add elements to the array.
for (int i = 0; i < 10; i++)
myArray.Add(CPoint(i, 2*i));
myArray.RemoveAll();
#ifdef _DEBUG
afxDump.SetDepth(1);
afxDump << "myArray: " << &myArray << "\n";
#endif
CArray::RemoveAt
Removes one or more elements starting at a specified index in an array.
void RemoveAt(
INT_PTR nIndex,
INT_PTR nCount = 1);
Parameters
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by GetUpperBound.
nCount
The number of elements to remove.
Remarks
In the process, it shifts down all the elements above the removed element(s). It decrements the upper bound of the array but does not free memory.
If you try to remove more elements than are contained in the array above the removal point, then the Debug version of the library asserts.
Example
CArray<CPoint,CPoint> myArray;
// Add elements to the array.
for (int i = 0; i < 10; i++)
myArray.Add(CPoint(i, 2*i));
myArray.RemoveAt(5);
#ifdef _DEBUG
afxDump.SetDepth(1);
afxDump << "myArray: " << &myArray << "\n";
#endif
CArray::SetAt
Sets the array element at the specified index.
void SetAt(INT_PTR nIndex, ARG_TYPE newElement);
Parameters
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by GetUpperBound.
ARG_TYPE
Template parameter specifying the type of arguments used for referencing array elements.
newElement
The new element value to be stored at the specified position.
Remarks
SetAt
will not cause the array to grow. Use SetAtGrow if you want the array to grow automatically.
You must ensure that your index value represents a valid position in the array. If it is out of bounds, then the Debug version of the library asserts.
Example
See the example for GetAt.
CArray::SetAtGrow
Sets the array element at the specified index.
void SetAtGrow(INT_PTR nIndex, ARG_TYPE newElement);
Parameters
nIndex
An integer index that is greater than or equal to 0.
ARG_TYPE
Template parameter specifying the type of elements in the array.
newElement
The element to be added to this array. A NULL value is allowed.
Remarks
The array grows automatically if necessary (that is, the upper bound is adjusted to accommodate the new element).
Example
// example for CArray::SetAtGrow
CArray<CPoint,CPoint> ptArray;
ptArray.Add(CPoint(10,20)); // Element 0
ptArray.Add(CPoint(30,40)); // Element 1
// Element 2 deliberately skipped
ptArray.SetAtGrow(3, CPoint(50,60)); // Element 3
CArray::SetSize
Establishes the size of an empty or existing array; allocates memory if necessary.
void SetSize(
INT_PTR nNewSize,
INT_PTR nGrowBy = -1);
Parameters
nNewSize
The new array size (number of elements). Must be greater than or equal to 0.
nGrowBy
The minimum number of element slots to allocate if a size increase is necessary.
Remarks
If the new size is smaller than the old size, then the array is truncated and all unused memory is released.
Use this function to set the size of your array before you begin using the array. If you do not use SetSize
, adding elements to your array causes it to be frequently reallocated and copied. Frequent reallocation and copying are inefficient and can fragment memory.
The nGrowBy
parameter affects internal memory allocation while the array is growing. Its use never affects the array size as reported by GetSize and GetUpperBound. If the default value is used, MFC allocates memory in a way calculated to avoid memory fragmentation and optimize efficiency for most cases.
Example
See the example for GetData.
See Also
MFC Sample COLLECT
CObject Class
Hierarchy Chart
CObArray Class
Collection Class Helpers