EXC_BAD_ACCESS 尝试删除有效指针时(xcode c++)

发布于 2024-12-25 02:38:00 字数 908 浏览 4 评论 0原文

我有一个名为 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,删除没有问题。在第二遍中,d 是 'FSCE::Customer' * 0x100897e00,当删除时,d 会导致 EXC_BAD_ACCESS。我可以访问调试器中第二个“d”的成员。即d->lifeid int 2,表明FSCE::Customer对象是一个有效的对象,并且'd'是一个有效的指针。

接下来我应该采取哪些步骤来查找 EXC_BAD_ACCESS 的原因?

I have a template class called OrdinalObjectList which is simply a map with a key of int and object pointers. It's purpose is to provide an collection of object pointers that can be accessed by an ordinal key. Here is the class:

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;
        }
    };

On destruction of the OrdinalObjectList, the destructor loops through the map and deletes the objects. This has worked fine up until now, however it is currently receiving a EXC_BAD_ACCESS error when deleting the second of two objects in the collection.

On the first pass d is 'FSCE::Customer' * 0x10088e600 which delete's without issue. On the second pass, d is 'FSCE::Customer' * 0x100897e00 which, when delete'd causes the EXC_BAD_ACCESS. I can access the members of the second 'd' in the debugger. i.e. d->lifeid int 2, indicating that the FSCE::Customer object is a valid object and that 'd' is a valid pointer.

What steps should I take next to track down the cause of the EXC_BAD_ACCESS?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷爱 2025-01-01 02:38:00

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

I can't tell for sure, but it is it possible your deleting the 1st and (nonexistent) 2nd items, rather than the 0th and 1st items? Make sure you're deleting what you think you're deleting.

喜爱皱眉﹌ 2025-01-01 02:38:00

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

对于 XCode 4.x,请参阅如何在 Xcode 4 中设置 NSZombieEnabled?

对于 XCode 的其他版本,您可以在互联网上找到它。

EXC_BAD_ACCESS can easily be traced by enabling zombie objects.

For XCode 4.x see How do I set up NSZombieEnabled in Xcode 4?

For other versions of XCode you can find it on the internet.

皇甫轩 2025-01-01 02:38:00

编辑:以下是不正确的。

这并不是一个真正的答案,但是当我将线程数减少到 4 时,问题就消失了。之前我把线程数设置为8,boxen是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”的代码的另一部分中的错误意味着有时索引会大于矩阵大小,这是我通过添加检查和抛出发现的。

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;
}

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

Edit: Below is incorrect.

Not really an answer, however when I reduced the number of threads to 4, the problem goes away. Previously I had set the number of threads to 8, the boxen is Core i7, which is 4 cores with Hyper Threading.

I can only assume that there is a problem with Hyper Threading, either in the OSX kernel or LLVM. I have optimisations set to O3, at some point I will turn off optimisations and see if that works on 8 threads, however in the meantime, 4 threads is only 10% slower than 8, so I will stick with that so I can progress.

The problem was with a large array within the objects I was deleting. The array was created in the constructor and deleted in the destructor similar to this (data member names have been changed):

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;
}

So far so good, however in setting the values in the matrix I had a bug.

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

The bug in another part of the code that set 'maxc' meant that sometimes index would be greater than matrixsize, which I discovered by adding a check and 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;
}

This would result in access to memory outside that which was allocated in the constructor, and when the delete was called, the EXC_BAD_ACCESS error being raised. The curious thing is why the EXC_BAD_ACCESS was not raised in Matrix::SetValue during execution, but I guess the answer has something to do with there being no bounds checking on array index offsets against the heap manager's memory bounds. If anyone can shed light on that I would be most interested, but for now, this answer is for anyone who finds this answer from a web search.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文