EXC_BAD_ACCESS当试图删除有效的指针(xcode c++)

EXC_BAD_ACCESS when trying to delete valid pointer (xcode c++)

本文关键字:指针 c++ 有效 xcode 删除 ACCESS BAD EXC      更新时间:2023-10-16

我有一个名为OrdinalObjectList的模板类,它只是一个带有int键和对象指针的映射。它的目的是提供一个对象指针的集合,这些对象指针可以通过顺序键访问。下面是类:

template <typename O>
class OrdinalObjectList {
public:
    std::map<int, O*> List;
    OrdinalObjectList() {};
    virtual ~OrdinalObjectList() 
    {
        // Need to delete the objects in the map
        typename std::map<int, O*>::iterator i;
        for (i = List.begin(); i != List.end(); i++)
        {
            O* d = i->second;
            delete d;
        }
    };

在销毁OrdinalObjectList时,析构函数循环遍历映射并删除对象。到目前为止,这还可以正常工作,但是在删除集合中两个对象中的第二个对象时,它目前会收到EXC_BAD_ACCESS错误。

在第一次传递d是'FSCE::Customer' * 0x10088e600,其中删除's没有问题。在第二次传递中,d是'FSCE::Customer' * 0x100897e00,当delete'd导致EXC_BAD_ACCESS。我可以访问调试器中第二个'd'的成员。即d->lifeid int 2,表明FSCE::Customer对象是一个有效的对象,并且'd'是一个有效的指针。

接下来我应该采取什么步骤来跟踪EXC_BAD_ACCESS的原因?

我不能确定,但是否有可能删除第1和(不存在的)第2项,而不是第0和第1项?确保你删除的是你认为你要删除的。

EXC_BAD_ACCESS可以通过启用僵尸对象轻松跟踪。

对于XCode 4。x见我如何设置NSZombieEnabled在Xcode 4?

其他版本的XCode可以在网上找到

编辑:下面是不正确的

不是真正的答案,但是当我将线程数量减少到4时,问题就消失了。之前我将线程数设置为8,箱子是Core i7,它是4核超线程。

我只能假设在OSX内核或LLVM中存在超线程问题。我将优化设置为O3,在某些时候我会关闭优化,看看这是否适用于8个线程,但与此同时,4个线程只比8个线程慢10%,所以我会坚持这样做,这样我就可以进步。

问题是我要删除的对象中有一个很大的数组。该数组在构造函数中创建,并在析构函数中删除,类似于以下操作(数据成员名称已更改):

Matrix::Matrix(int maxa, int maxb, int maxc) 
{
  asize = maxa;
  bsize = maxb; 
  csize = maxc;
  matrixsize = a * b * c;
  matrix = new double [matrixsize];
}
Matrix::~Matrix()
{
  delete [] matrix;
}

到目前为止一切顺利,但是在设置矩阵中的值时,我有一个错误。

void Matrix::SetValue(int a,int b,int c,double value)
{
  int index = (a * asize) + (b * bsize) + c;
  matrix[index] = value;
}

设置'maxc'的另一部分代码中的错误意味着有时index会大于matrixsize,这是我通过添加check和throw发现的。

void Matrix::SetValue(int a,int b,int c,double value)
{
  int index = (a * asize) + (b * bsize) + c;
  if (index >= matrixsize) throw;
  matrix[index] = value;
}

这将导致访问构造函数中分配的内存之外的内存,并且当调用delete时,会引发EXC_BAD_ACCESS错误。奇怪的是,为什么在执行期间Matrix::SetValue中没有引发EXC_BAD_ACCESS,但我猜答案与没有针对堆管理器的内存边界检查数组索引偏移有关。如果有人能阐明这一点,我将最感兴趣,但现在,这个答案是给任何从网络搜索中找到这个答案的人。