0

I can't seem to figure out a way to prevent this block of code from crashing:

CArray<Mat, Mat> ary;
for(int i = 0; i < 5; i++)
{
    Mat rawmat(5,5,CV_8U);
    ary.Add(rawmat);
}
for(int i = 0; i < 5; i++)
{
    ary.GetAt(i).release();
}
ary.FreeExtra();
ary.RemoveAll();

I've also tried using a reference via:

CArray<Mat, Mat&> ary;

Same issue. This doesn't occur with a CList, but I'd rather use a CArray for random iteration purposes.

Goober
  • 211
  • 3
  • 9

1 Answers1

4

CArray is an old MFC container class, with an old design.

I'd recommend using a more modern approach, with STL containers, like std::vector (instead of CArray).

You can use std::vector::push_back() to add new items to it.
And if you want to clear all vector's content, you can call its clear() method.

#include <vector>  // for using std::vector

....

// Create an empty std::vector
std::vector<Mat> arrayOfMats;

// Use vector::push_back() to add new items to it
Mat someMat(...);
arrayOfMats.push_back(someMat);

You can use std::vector::size() to get the number of items stored in the vector.

And you can iterate through the vector content using an integer index upper-bounded to the vector's size (similar to what you did with CArray), or just using the new C++11's range-for loop syntax.


Note that you can still use other MFC classes for other parts of your applications, e.g. for the GUI, for Windows API interaction, etc.
STL's container classes like std::vector can just be used in the "business logic", in the "core" of your application code.


Going deeper into your problem, it seems that the Mat class you used in your code (probably from OpenCV, considering one of your question tag...) is not "trivially copyable" using memcpy (or its safer memcpy_s version), so it is not a good candidate for simple use with CArray, as you can read in the CArray MSDN documentation (emphasis mine):

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.

Instead, note how this kind of problem does not occur with std::vector, which plays nice with non-trivially-copyable classes.

Community
  • 1
  • 1
Mr.C64
  • 41,637
  • 14
  • 86
  • 162