Задача C Управление памятью - ошибки "освобожден указатель не выделен"
Я пытаюсь изучить цель-c (я очень новичок в этом), и у меня есть проблемы с управлением памятью...
Я разрабатываю приложение для iPad, которое использует TouchXML.
Я создал свой класс, который расширяет CXMLDocument и выполняет некоторую инициализацию, читая некоторое содержимое и сохраняя его в свойствах.
Вот мой код (SimpleManifest.h):
@interface SimpleManifest : CXMLDocument {
CXMLNode *_defaultOrganization;
NSString *_title;
NSDictionary *dictionary;
}
@property (readonly) CXMLNode *defaultOrganization;
@property (readonly) NSString* title;
- (id) initWithPath:(NSString *)path options:(NSUInteger)options error:(NSError **)error;
@end
(SimpleManifest.m):
#import "SimpleManifest.h"
#import "CXMLNode_XPathExtensions.h"
@implementation SimpleManifest
- (id) initWithPath:(NSString *)path options:(NSUInteger)options error:(NSError **)error
{
/*
NSURL *theURL = [[[NSURL alloc] initFileURLWithPath:path] autorelease];
self = [self initWithContentsOfURL:theURL options:options error:error];
*/
NSData *data = [NSData dataWithContentsOfFile:path];
NSString *s = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
self = [self initWithXMLString:s options:options error:error];
if (self==nil) return nil;
// load main props
dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
@"http://www.imsglobal.org/xsd/imscp_v1p1", @"imscp",
@"http://ltsc.ieee.org/xsd/LOM", @"lom", nil];
// defualt organization
@try {
CXMLNode *orgsElem = [[[self childAtIndex:0] nodesForXPath:@"//imscp:organizations" namespaceMappings:dictionary error:nil] objectAtIndex:0];
NSString *xpath = [NSString stringWithFormat:@"//imscp:organization[@identifier='%@']", [[orgsElem attributeForName:@"default"] stringValue]];
_defaultOrganization = [[[self childAtIndex:0] nodesForXPath:xpath namespaceMappings:dictionary error:nil] objectAtIndex:0];
/*
NSArray *nodes = [[self childAtIndex:0] nodesForXPath:@"//imscp:organizations" namespaceMappings:dictionary error:nil];
NSString *xpath = [NSString stringWithFormat:@"//imscp:organization[@identifier='%@']", [[[nodes objectAtIndex:0] attributeForName:@"default"] stringValue]];
_defaultOrganization = [[[self childAtIndex:0] nodesForXPath:xpath namespaceMappings:dictionary error:nil] objectAtIndex:0];
*/
CXMLNode *titleElem = [[[self childAtIndex:0]
nodesForXPath:@"//lom:general/lom:title/lom:string"
namespaceMappings:dictionary
error:nil] objectAtIndex:0];
_title = [[titleElem stringValue] copy];
} @catch (NSException * e){
self = nil;
return nil;
}
return self;
}
@end
Позже в другом классе я делаю:
- (BOOL) isValidSCORMLesson:(NSString*) path {
NSString *manifPath = [path stringByAppendingPathComponent:@"imsmanifest.xml"];
if (![[NSFileManager defaultManager] fileExistsAtPath: manifPath isDirectory: NO])
return NO;
SimpleManifest *manifest = [[[SimpleManifest alloc] initWithPath:manifPath options:0 error:nil] autorelease];
NSLog(@"%@", manifest.defaultOrganization);
NSLog(@"%@", manifest.title);
return (manifest!=nil);
}
Это дает мне кучу ошибок "освобожден указатель не был выделен"... Ситуация меняется, если я закомментирую вышеприведенные вызовы NSLog или просто зарегистрирую свойство manifest.title. Проект не использует ARC, поэтому я уверен, что делаю что-то не так с управлением памятью.
Может кто-нибудь, пожалуйста, помогите мне понять, где я делаю неправильно? Спасибо!
1 ответ
В этом коде нет ничего явно неправильного, что могло бы вызвать ошибки malloc. Лучше всего предположить, что в классе / библиотеке CXMLDocument есть ошибка или какая-то ошибка в том, как вы ее используете.
Обратите внимание, что "освобожденный указатель не был выделен" означает, что кто-то вызвал free()
(или же dealloc
эффективно) на указатель на фрагмент памяти, который не был выделен в первую очередь. Обычно это дает вам точку останова, которую вы можете установить, которая затем даст вам точный след того, где это произошло.
Некоторые комментарии:
(1) Не пытайтесь делать это таким образом. Просто не лови вообще. Шаблон, который вы используете, будет скрывать любые ошибки. Исключения не предназначены для восстановления в iOS/ Какао.
(2) Вы можете создать NSString
экземпляр прямо из файла; нет необходимости загружать через NSData
первый.
(3) Вы должны использовать ARC.