为什么在这个实例中使用RemovAll()时CArray会崩溃?

时间:2014-11-18 18:07:07

标签: c++ opencv visual-c++ mfc

我似乎无法找到防止此代码块崩溃的方法:

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();

我也尝试过使用引用:

CArray<Mat, Mat&> ary;

同样的问题。 CList不会发生这种情况,但我更倾向于使用CArray进行随机迭代。

1 个答案:

答案 0 :(得分:3)

CArray MFC容器类,采用旧设计。

我建议使用更现代的方法,使用STL容器,例如 std::vector (而不是CArray)。< / p>

您可以使用std::vector::push_back()向其添加新项目 如果您想清除所有向量内容,可以调用其clear()方法。

#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);

您可以使用std::vector::size()来获取向量中存储的项目数。

您可以使用上限为向量大小的整数索引(类似于您对CArray所做的那样)迭代向量内容,或者只使用new C++11's range-for loop syntax


请注意,您仍然可以将其他MFC类用于应用程序的其他部分,例如:用于GUI,用于Windows API交互等。
std::vector这样的STL容器类只能用于&#34;业务逻辑&#34;,&#34;核心&#34;您的应用程序代码。


更深入地解决您的问题,您的代码中使用的Mat类(可能来自OpenCV,考虑到您的问号之一......)似乎不是&# 34;可轻易复制&#34;使用memcpy(或更安全的memcpy_s版本),因此它不适合与CArray一起使用,因为您可以阅读the CArray MSDN documentation强调雷):

  

调整CArray对象大小或向其添加元素的大多数方法都使用memcpy_s来移动元素。这是一个问题,因为memcpy_s是   与任何需要构造函数的对象都不兼容   被叫。如果CArray中的项目不兼容   memcpy_s,您必须创建适当大小的新CArray。   然后,您必须使用CArray::CopyCArray::SetAt填充   新数组,因为这些方法使用赋值运算符而不是   memcpy_s

相反,请注意std::vector如何发生 not 这样的问题,这对于非平凡可复制的类来说非常好。