Сбой программы — вероятно, неправильное использование памяти

#objective-c

#objective-c

Вопрос:

У меня есть массив объектов Objective-C, который должен быть отсортирован по полю объекта. Я использую простую сортировку выбора, поскольку массив небольшой. Сортировка работает, и правильные данные находятся в массиве, но после добавления около 3 или 4 объектов в массив и повторного использования при каждом сбое. Любая помощь будет оценена. Ошибка EXC_BAD_ACCESS Заранее спасибо. Код следует:

 TopTenDataClass *temp1 = [[TopTenDataClass alloc] init];
TopTenDataClass *temp2 = [[TopTenDataClass alloc] init];
for (int i = 0; i < [topTenDataArray count]; i  )
{
    int minIndex = i;
    for (int j = i; j < [topTenDataArray count]; j  )
    {
        temp1 = [topTenDataArray objectAtIndex:minIndex];
        temp2 = [topTenDataArray objectAtIndex:j];
        if ( temp2.timeInSeconds < temp1.timeInSeconds)
            minIndex = j;
    }
    [topTenDataArray exchangeObjectAtIndex:minIndex withObjectAtIndex:i];
}
[temp2 release]; [temp1 release];
  

Комментарии:

1. Интересно, что утечки памяти редко вызывают сбои, это одна из причин, по которой их так трудно найти.

Ответ №1:

Проблема в том, что внутри вашего цикла вы меняете значения temp1 и temp2 . Когда вы освобождаете их после завершения цикла, вы не освобождаете объекты, которые вы создали до запуска цикла. Вместо этого вы пытаетесь освободить какой-то другой объект, который вы не выделяли / инициализировали (в этой части кода). Вероятно, именно это и является причиной вашего сбоя.

Я бы предложил попробовать что-то вроде:

 TopTenDataClass *temp1 = nil;
TopTenDataClass *temp2 = nil;
for (int i = 0; i < [topTenDataArray count]; i  )
{
    int minIndex = i;
    for (int j = i; j < [topTenDataArray count]; j  )
    {
        temp1 = [topTenDataArray objectAtIndex:minIndex];
        temp2 = [topTenDataArray objectAtIndex:j];
        if ( temp2.timeInSeconds < temp1.timeInSeconds)
            minIndex = j;
    }
    [topTenDataArray exchangeObjectAtIndex:minIndex withObjectAtIndex:i];
}
  

Вам не нужно назначать новый экземпляр объекта перед temp1 циклом и temp2 перед ним, потому что вы просто перезаписываете их значения внутри своего цикла.

Также обратите внимание, что если topTenDataArray в нем есть только один элемент, ваш код будет вызывать [topTenDataArray exchangeObjectAtIndex:0 withObjectAtIndex:0] , что также может быть проблемой (в документах API не говорится, что вы не можете обмениваться объектом с самим собой, но они также не говорят, что вы можете).

Комментарии:

1. Удивительно, в версии, которая работает, меньше кода! Это случается часто, больше кода == больше шансов совершить ошибку.

2. wroth — Большое СПАСИБО — это было так. Ценю помощь