Простая цель - C переоценка, что * следует * Crash не сбивается. Почему?

StackOverflow https://stackoverflow.com/questions/4079198

Вопрос

Либо мой отладчик нарушен, либо есть что-то фундаментальное, что я не понимаю.

У меня есть очень базовый код в очень базовой программе командной строки, которая должен крушение. Тем не менее, это не разрушается.

int main (int argc, const char * argv[])
{
    NSString *string = [[NSString alloc] initWithString:@"Hello"];

    [string release];

    NSLog(@"Length: %d", [string length]);

    return 0;
}

Заявление журнала печатает «Длина: 5», поскольку вы ожидаете для действительной строки. Однако строка должна быть оформлена в этой точке и exec_bad_access Ошибка должна быть брошена.

Я попробовал этот код с прикрепленным отладчиком и без подключенного отладчика - оба дают тот же результат. Я также включен (и отключен) NSZombie, что, кажется, не имеет никакого эффекта (я изначально подумал, что это проблема, поскольку NSZombie Объекты никогда не оформлены - но это все еще не врезается с NSZombie инвалид).

У меня есть точки останова, установленные в моем местном .gdbinit файл, чтобы сломаться на таких вещах, как -[NSException raise] а также objc_exception_throw. Отказ У меня также есть точки останова, установленные на многих методах на NSZombie чтобы поймать их.

fb -[NSException raise]
fb -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:]
fb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]

#define NSZombies
# this will give you help messages.  Set to NO to turn them off.
set env MallocHelp=YES
# might also be set in launch arguments.
set env NSZombieEnabled=YES
set env NSDeallocateZombies=NO
set env MallocCheckHeapEach=100000
set env MallocCheckHeapStart=100000
set env MallocScribble=YES
set env MallocGuardEdges=YES
set env MallocCheckHeapAbort=1

set env CFZombie 5

fb -[_NSZombie init]
fb -[_NSZombie retainCount]
fb -[_NSZombie retain]
fb -[_NSZombie release]
fb -[_NSZombie autorelease]
fb -[_NSZombie methodSignatureForSelector:]
fb -[_NSZombie respondsToSelector:]
fb -[_NSZombie forwardInvocation:]
fb -[_NSZombie class]
fb -[_NSZombie dealloc]

fb szone_error
fb objc_exception_throw

С этими точками останова и включена Nszombie, я должен получить что-то вроде [NSString length]: message sent to deallocated instance 0x100010d39 напечатано на консоль, но я этого не вижу. Я вижу NSLog Печать длины как 5.

Я вижу подобное поведение с другими классами, такими как NSURL а также NSNumber. Отказ Но некоторые классы аварии, как и ожидалось, такие как NSError а также NSObject.

Есть ли у этого есть что делать с классовыми кластерами? Они не следуют тому же правилам в отношении управления памятью?

Если классовые кластеры не связаны с этой проблемой, единственная прочая общая функция, которую я мог видеть, заключалась в том, что классы, которые не сбиваются таким образом, - все бесплатные модифицированные бесплатные с помощью основного фундамента. Может ли это иметь что-то связанное с этим?

Это было полезно?

Решение

retain/release Договор между API и программистом, который, когда вы следите за правилом, он не сбивается. Контракт не гарантирует, что если вы не будете следовать правилу, он работает сбой!

В этом случае,

[[NSString alloc] initWithString:@"Hello"]

просто возвращает тот же объект, что и @"Hello" как оптимизация. Константа NSString никогда не освобожден; как оптимизация, retain а также release Есть (я думаю) игнорировал. Вот почему это не хватает.

Вы можете проверить свое предположение, сравнивая значение указателя @"Hello" а также string.

Другие советы

Это отличный пример того, почему уход за сохранением является довольно бесполезный инструмент отладки. Ошибка предположить -retake и -release всегда добавлять или удалять 1 из удержанного подсчета, и что подсчет сохранения - это то, что вы думаете, что должно быть.

Пытаться

NSString *string = [[NSString alloc] initWithFormat:@"Hello %d", argc];

Это должно дать вам строку, которая будет вести себя больше похоже на то, как вы ожидаете, поскольку вы не инициализируете свою строку из постоянной времени компиляции. Однако следует предупредить, с включенным зомби, вы получите поведение, которое вы ожидаете, но без зомби, NSLog может работать хорошо. Хотя строка была освобождена, данные в объекте все еще там в памяти, оставляя «призрак», который будет правильно отвечать на некоторые сообщения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top