EXC_BAD_ACCESS при попытке удалить действительный указатель (xcode c ++) - PullRequest
0 голосов
/ 05 января 2012

У меня есть шаблонный класс с именем OrdinalObjectList, который представляет собой просто карту с ключом указателей типа int и object. Его цель - предоставить коллекцию указателей объектов, к которой можно получить доступ по порядковому ключу. Вот этот класс:

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, которое, когда delete 'd вызывает EXC_BAD_ACCESS. Я могу получить доступ к членам второго «d» в отладчике. то есть d-> lifeid int 2, указывающий, что объект FSCE :: Customer является допустимым объектом, а 'd' является действительным указателем.

Какие шаги мне следует предпринять, чтобы отследить причину EXC_BAD_ACCESS?

Ответы [ 3 ]

0 голосов
/ 05 января 2012

Редактировать: ниже неверно.

Не совсем ответ, однако, когда я уменьшил количество потоков до 4, проблема исчезла.Ранее я установил число потоков равным 8, boxen - это Core i7, то есть 4 ядра с Hyper Threading.

Я могу только предположить, что существует проблема с Hyper Threading, либо в ядре OSX, либоLLVM.У меня настроены оптимизации на O3, в какой-то момент я отключу оптимизацию и посмотрю, работает ли она на 8 потоках, однако в то же время 4 потока работают только на 10% медленнее, чем 8, поэтому я буду придерживаться этого, чтобы я мог прогрессировать.

Проблема была в большом массиве в объектах, которые я удалял.Массив был создан в конструкторе и удален в деструкторе, аналогичном этому (имена членов данных были изменены):

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', означала, что иногда индекс был больше размера матрицы, что я обнаружил, добавив 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;
}

Это приведет к доступу к памяти вне той, которая была выделена в конструкторе, и когда вызывается удаление, возникает ошибка EXC_BAD_ACCESS.Любопытно, что EXC_BAD_ACCESS не был вызван в Matrix :: SetValue во время выполнения, но я предполагаю, что ответ имеет какое-то отношение к тому, что нет проверки границ на смещения индекса массива по отношению к границам памяти менеджера кучи.Если кто-то может пролить свет на это, мне было бы очень интересно, но сейчас этот ответ предназначен для всех, кто находит этот ответ в веб-поиске.

0 голосов
/ 05 января 2012

EXC_BAD_ACCESS можно легко отследить, включив объекты-зомби.

Для XCode 4.x см. Как настроить NSZombieEnabled в Xcode 4?

Для других версий XCode вы можете найти его в Интернете.

0 голосов
/ 05 января 2012

Не могу сказать точно, но возможно ли, что вы удалили 1-й и (несуществующий) 2-й элементы, а не 0-й и 1-й элементы?Убедитесь, что вы удаляете то, что, по вашему мнению, удаляете.

...